Restrict public web application access to specific dynamic source IP addresses - laravel

I'm developing a web application using Laravel hosting on a public cloud. Now, the application can be accessed publicly on the internet via domain address. However, I want to restrict to only users who are connecting to the organization networks to be able to use the application since we do not want the application to be used at home or elsewhere.
At the moment, the organization has 2 places (2 public internet networks) where they must be able to access to the application. Both of them are using home-standard internet where IP address changes every time the internet reconnects. As we do not have static IP addresses, I cannot filter user by using IP address filter. The IP filter rule must be changed every time when the organization network reconnected.
My application already have solid authentication and authorization mechanism and, of course, the users must know this information since they must access the app for work. However, this doesn't meet the requirement.
I have thought about the VPN but it (probably) doesn't not work because if we allow user the access to the VPN, they still be able to access the VPN anywhere and use the application outside the work places. If we restrict the VPN client to access from specific IP address, then when the IP changes, the same problem occurs.
To sum up, I would like to ask for the advice on how to restrict the access of web application, hosted on public internet, to the users that are connecting from the public IP address that can change every time when the internet reconnected. The requirement may sound strange but it is as it is. Please feel free to ask for more details if you want to and have a discussions on the suggestions.
Thank you in advance.

You could setup a client for a dynamic dns service (e.g. dyndns) on the client-side.
Then you could use that on the server-side to always check against current IP using that dns.
As alternative you could bind the website to localhost only and only let it be accessed via an pubkey-enforced SSH tunnel (and make that get auto-established by a script/scheduler on the client side, on a permission level outside of the users' reach, so that they can't take the private key needed for the connection anywhere)

You can use different PHP methods and variables to detect from where the request has been originated. Just whitelist your domains and organizations, and allow only them by adding a middleware.
Additionally, you can generate a token using Laravel Passport or you can create your own mechanism, and then use that token to authenticate if the request is valid or not.
Since the IP changes, you can setup a dynamic dns or as suggested on the comment above.

Related

Custom domains for Multi-tenant web app

I am developing an app (RoR + Heroku) which allows users create their own websites either using my subdomain (pagename.myapp.com) or using their own domain (pagename.com).
An important point of this is that this option is the key of my business: subdomains are the free plans and custom domains are the paid ones. So I have a table where I store the custom domains of each user and check if this page is active (exists and has paid the quota).
For that I need to give users the capability of point their domain to my servers. All we know that Heroku don't recommend the use of DNS A-Records.
Also I would like to abstract as much as possible this feature to being able to switch my infrastructure (Heroku to AWS) in the future without having to ask all my users to change their DNS Zone. Taking this into account, I think that the best option would be run something like an EC2 proxy (using AWS Elastic IP) which give me the ownership of this IP. This proxy I think that should redirect to proxy.myapp.com, and I would resolve the request in the app level.
Due to I didn't find clear information about that, I am not sure if this hypotesis is the best solution and how to setup the proxy (which type of proxy use? Nginx maybe?).
Said that, I would like to ask recommendations/best practices to solve this "common" feature.
Thanks
What you are wanting to do is fairly straight forward to implement. Your assumptions are correct about setting up the proxy. Nginx or haproxy will both work great for this (I personally would use haproxy). Here are some of the gotchas that you will run into though:
Changing the host header at a proxy server can cause the end web application to generate incorrect links. You can use relative paths to fix this, but it requires that the web application developer to be aware of the environment that they are running in.
user connects to www.example.com (proxy server)
proxy server connects to www.realdomain.com (web app)
the web app has a link for a shopping cart. www.realdomain.com/shoppingcart
the end user clicks on the link but the link is www.realdomain.com/shoppingcart instead of www.example.com/shoppingcart
The cost of the host acting as the proxy server. This can spiral out of control really quickly. For example, do you want redundancy, if so how are you planning on implementing that? Do you plan on having ssl termination? If so you will have to increase the CPU count to accommodate the additional load. Do you want to have a secure connection to heroku from your proxy? If you do then you will need to increase the CPU count for that as well. You may have to add additional ram as well depending on the number of concurrent connections.
Heroku also changes their load balancers regularly. This is important because your proxy service will need to reload the config / update the ip addresses of the heroku instances every 60 seconds. In my experience they may change once or twice a day, but the DNS entry that they use has a 60 second TTL. That means that you should make sure that you are capable of updating your config up to every 60 seconds.
My company has been doing something very similar to this for almost a year now. We use haproxy and simply have it reload the config regularly. We have never had an outage or an interruption to our end users. Nginx is also a very good product. It has built in DNS caching so if you go that route you will need to make sure that you configure it correctly so that the DNS cache TTL is 60 seconds.
Will many of your clients want to use your app on their domain apex? E.g. example.com rather than theapp.example.cpm? If not, I would recommend having them CNAME to proxy.myapp.com which CNAMEs to myapp.herokuapp.com. Then, you can update proxy.myapp.com without customer interruption.
If you do need apex or A record support, you would want to set up Nginx as a reverse proxy for your Heroku app. Keep in mind that if you need HTTPS support for client domains, you will need to do some sort of certificate management on your proxy.
I like the answer dtorgo gave and that he mentioned the TLS termination, which many online tutorials on custom domains don't touch at all.
I'll go into more detail on how to implement the custom domains feature for your SaaS while also handling the TLS/HTTPS.
If your customers just CNAME to your domain or create the A record to your IP and you don't handle TLS termination for these custom domains, your app will not support HTTPS, and without it, your app won't work in modern browsers on these custom domains.
You need to set up a TLS termination reverse proxy in front of your webserver. This proxy can be run on a separate machine but you can run it on the same machine as the webserver.
CNAME vs A record
If your customers want to have your app on their subdomain, e.g. app.customer.com they can create a CNAME app.customer.com pointing to your proxy.
If they want to have your app on their root domain, e.g. customer.com then they'll have to create an A record on customer.com pointing to your proxy's IP. Make sure this IP doesn't change, ever!
How to handle TLS termination?
To make TLS termination work, you'll have to issue TLS certificates for these custom domains. You can use Let's Encrypt for that. Your proxy will see the Host header of the incoming request, e.g. app.customer1.com or customer2.com etc., and then it will decide which TLS certificate to use by checking the SNI.
The proxy can be set up to automatically issue and renew certificates for these custom domains. On the first request from a new custom domain, the proxy will see it doesn't have the appropriate certificate. It will ask Let's Encrypt for a new certificate. Let's Encrypt will first issue a challenge to see if you manage the domain, and since the customer already created a CNAME or A record pointing to your proxy, that tells Let's Encrypt you indeed manage the domain, and it will let you issue a certificate for it.
To issue and renew certificates automatically, I'd recommend using Caddyserver, greenlock.js, OpenResty (Nginx).
tl;dr on what happens here;
Caddyserver listens on 443 and 80, it receives requests, issues, and renews certificates automatically, proxies traffic to your backend.
How to handle it on my backend
Your proxy is terminating TLS and proxying requests to your backend. However, your backend doesn't know who is the original customer behind the request. This is why you need to tell your proxy to include additional headers in proxied requests to identify the customer. Just add X-Serve-For: app.customer.com or X-Serve-For: customer2.com or whatever the Host header is of the original request.
Now when you receive the proxied request on the backend, you can read this custom header and you know who is the customer behind the request. You can implement your logic based on that, show data belonging to this customer, etc.
More
Put a load balancer in front of your fleet of proxies for higher availability. You'll also have to use distributed storage for certificates and Let's Encrypt challenges. Use AWS ECS or EBS for automated recovery if something fails, otherwise, you may be waking up in the middle of the night restarting machines, or your proxy manually.
If you need more detail you can DM me on Twitter #dragocrnjac

Siteminder bypass authentication for specific IP address

I have a resource/url that is protected by siteminder. I would like to allow access to url for anyone coming from a specific IP address range.
If a browser is from a specific IP address range, I don't want them to Authenticate, they need to see the url without being prompted to log in.
Is there a way in siteminder to allow open access for specific IP address ranges, but require login for anyone outside of that range?
thanks
This is probably a bad idea security wise since an IP address could be spoofed leaving your application completely open. If you still wanted to continue I would look into using a load balancer/proxy to forward the request to another agent with a separate configuration.

Magento Developer Client Restrictions

Whan I attempt to use Developer Client Restrictions, should I use my LAN IP address or my public IP address? I am accessing the site remotely. I assume it\’s the public IP, but I just want to be sure.
The Developer Client Restrictions setting does not restrict access to the site. Rather, that setting is evaluated in several different contexts to determine whether certain developer-related behaviors such as logging and template path hints should display. (It's sometimes buggy, e.g. breadcrumb block behavior with FPC & that setting turned on).
You will need to use the address which will be provided to the application via $_SERVER['REMOTE_ADDR'] (your public IP in this case).

Map my domain name with my own server

Hi I am having my own domain mydomain.ac.in and i am having my own server (windows 2008) and a Public static IP.
Now i want to host my site in my own server.
Please give me the step by step information to get it done.
Thanks.
You need to register your domain with some DNS hosting service (DNS provider), there is such an astronomic number of these on the web that I do not want to spam the site. Google.
Also, collocation center where you keep this server (and from where you have probably obtained that public IP) may also provide DNS services.
From the other side, any computer can be configured as the name server but this will probably not work Internet wide and can be used inside the local network only (combined with DHCP service). If there is an easy way to make this Internet wide, I would also be very interested in, but I doubt.
Your operating system is not much relevant to this question.
I registered my domain already in ernet by indian Government and I got my Public Static IP from BSNL India. I hosted my site already and i am able to access my site already using the ip. Now i want to map my domain with the server that i have so that i can access my domain using a domain name.
I tried the steps in http://www.hosting.com/support/dedicated/dns/setdns#additional.. But when i add the name server information it says cannot resolve hostname??? that s why i want to know where i am making mistake..
I once again tried the steps at http://www.hosting.com/support/dedicated/dns/setdns and got it right..Now i have updated the name server info at my domain registrar ernet and waiting for it to be updated. Thanks fo the people helped me

Directing dynamic subdomains to particular servers

We're building a multitenant SAAS app. Each customer gets its own subdomain, http://customername.mycompany.com. Each customer will have many gigabytes of data, which means that they have to be assigned to a particular server and stay there.
If I have a server farm, and a request comes in for a particular customer, how do I direct the request to the right server?
My thought is that I'll have to create some kind of custom, programmable load balancer that will know where each customer lives and proxy the request through.
Is there an easier way?
If not, where do I find such a load balancer? The ones I've found online act more like appliances than applications which could go query a database to find the right destination server.
I think the answer is in the question; you mention that the user will connect to username.mycompany.com. So use a DNS A record to point them to a particular IP.
In the future, if you wanted to load balance the user across (say 2) servers, you could create a virtual IP on a load balancer appliance (running LVS for example), and then point the A record to the Virtual IP created by the LB, and distribute the user across a group of servers that you have configured.
This is why using subdomains is simpler than having URL based access such as company.com/username, in which case you would have to inspect the content of the packet to see the requested URL. By using subdomains, everything can be done at the IP layer.

Resources