Can a node.js server be named like a directory location? - node.js

In node.js how do I create a server accessible with a name not a port?
instead of:
https://example.com:port
this kind of thing:
https://example.com/name/

A server (of any kind) is only named by the domain and port in the URL - it not named by the path at all. The browser parses the URL, takes the domain and port, looks up that domain in DNS to get the IP address, then makes a TCP connection to that specific IP address and port. So, in your example, that would be:
https://example.com:port
or
https://example.com
where the latter just uses the default port of 80. Only those portions of the URL specify the server that the browser will connect to. The path is then sent to that server and the server can then decide what it wants to do with that path when it receives the request.
That said, there are server-side tools you can use that will handle a request at the above server, look at the path and then forward that request to a different server/port. This is often called a proxy server. So, for example, you can run nginx (a pre-built, configurable proxy) that will let you configure that you want a request to https://example.com/name/ to go to some other host (which you can configure as some other IP address and port).
The browser will connect to example.com (which is your proxy) and send the http request for /name. The proxy will receive that request, look at the path, see that it is configured to forward that request to a different host, then connect to that other host, send the request to it, get the response back, then return the response back to the browser. The browser will not necessarily know that this "forwarding" is going on behind-the-scenes. It makes a request and gets an answer.

Related

How might one set up a reverse proxy that cannot decrypt traffic?

I'd like to have a reverse HTTPS proxy that CANNOT decrypt proxied traffic (ie an HTTPS passthrough/tunnel). The idea is to run this proxy on a VPS and point a domain to it, allowing for the IP address of the origin server to remain unexposed while maintaining end-to-end encryption.
Is this possible? I could probably proxy requests without difficulty since the destination address in that direction is fixed, but proxying responses seems problematic given that the proxy would be unable to read the client IP within an encrypted response.
A potential solution is to have the origin server package the encrypted response and destination address in a request made to the proxy, but I am unsure as to how I might generate the encrypted request without sending it (using node.js, which is the application running on the origin server).
From your question, I got that you want to listen to requests from your VPC server and pass the request to your other server which has to remain unexposed.
This can be configured with the web server which you are using for proxy ( considering AWS allows port forwarding from a VPN server to non-VPN server ).
I prefer doing this with Nginx as it is easy, open-source with less code and more functionality.
There is a concept of load balancing which does the same as you mentioned above.
steps :
Install Nginx and keep it active.
Create a new configuration file in /etc/nginx/sites-enabled
write the below code with modifications:
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
and at the place of srv1.example.com and srv2.example.com add the domain to which you want to redirect requests
Save the file and restart the Nginx
Boom!! it should redirect all incoming requests to your application.

Is there a way to identify express server-to-server request origin

Is there a way to obtain the origin information of a remote server making requests to my api server? The objective is to prevent possible server-to-server authentication token spoofing.
To test, I basically sent remote requests to the server from a test server listening on port 8000. While the req.connection.remote.address logged by the api server was consistent, the req.connection.remote.port changed with every request.
Is there a way to obtain the address of the test server along with its port 8000 from the request object at the api server? An outside of the box solution would be appreciated as well.
Is there a way to obtain the address of the test server along with its port 8000 from the request object at the api server?
No, there is not unless the requesting server specifically provides that information for you in a non-standard (custom) header. It is not part of TCP/IP or HTTP that you would know anything about what type of http client it is that is making the request or that it's even actually an http server making a request of your http server. From the networking point of view, it's just some http client at some IP address and you don't know anything about what else that http client might be doing (in your case also an http server).
An incoming TCP/IP connection never comes from the public, incoming port of the requesting web server. Instead, it comes from some dynamically assigned outbound port that is likely different for every request. That's how TCP/IP works. Outbound ports are dynamically assigned when the socket is created and they come from a different port range than is typically used for listening for incoming requests.
If the request is originating from a cooperating server, then you can ask it to set a custom header that indicates what port it is running on for incoming requests, but if it's not a cooperating server, there is no way for you to know what port is listens for incoming requests or if even it is a server at all.

ip module returning different ip addresses

I am using the ip library of npm.
I have two config files, one for React and one for Node, for the same application.
const ip = require('ip');
console.log(ip.address());
This returns different ip addresses for the React config file(inside the src folder-127.0.0.1) and Node server file(outside the src folder - IPv4 address).
The issue is that I am pretty sure that I ran the exact same code earlier and it gave me the same ip addresses for both as then I was able to access my webpages. I need the same ip to make requests to my node backend, I cannot afford it in production. Are there other definite methods of doing this?
You get different ip results because 2 method call ip.address() are using different network interfaces.
To make ip.address() return identical result, you can pass network interface name as the first parameter, such as en0:
const ip = require('ip');
console.log(ip.address('en0'));
p.s. To get all current networks interface names, os.networkInterfaces() can be used.
Update: OP try to get IP address in React code, in browser side. This is mission impossible. Otherwise, it would bring huge security problem.
Update 2: OP don't want to store endpoint IP address in frontend code for security reason, neither want to retrieve the IP address first (network overhead issue). In this case, you can make a proxy in server. All frontend know is interacting with current server, the data exchange is delivered by server as:
Browser <--> Server <--> Various endpoint IP
The steps are:
The server (that host the frontend code) get request from browser
Server check which endpoint would be used for that client
Server send the request to specific endpoint
Server get response from endpoint
Server return the response in above step to browser

How does Host header help on a physical host hosting multiple Servers?

I have 1 single machine with an IP 1.2.3.4. This machine has 2 web servers and an ftp server:
Web Server 1 listens to port 82; the domain for it: ws1.example.com
Web Server 2 listens to port 83; the domain for it: ws2.example.com
FTP Server listens to port 21; the domain for it: ftp.example.com
This is what the DNS mapping looks like:
ws1.example.com CNAME example.com
ws2.example.com CNAME example.com
ftp.example.com CNAME example.com
example.com A 1.2.3.4
Case 1: I make a request at the browser URL ws1.example.com:82 and the DNS redirects me to example.com but with the Host header: ws1.example.com.
Case 2: I make a request at the browser URL ws2.example.com:83 and the DNS redirects me to example.com but with the Host header: ws2.example.com.
In both the cases:
the request ultimately reaches the same physical machine
when the request arrives:
In Case 1, the request arrives at this machine and the request is attended to by the application that is listening on port 82 i.e. Web Server 1.
In Case 2, the request arrives at this machine and the request is attended to by the application that is listening on port 83 i.e. Web Server 2.
The Host header, as I understand, is used to inform the receiving host to identify which server (from the multiple servers that this IP has been hosting) is this request meant for and accordingly directs the request to the appropriate application.
My question is:
In this example, what is the purpose of the Host header as the same physical machine with the same IP has multiple applications listening at their corresponding ports. Once the request reaches this machine, the appropriate port will anyway pick up and the other applications will ignore the request as the port does not match the request. So, what purpose is the Host header serving here when apprpriate ports are anyway doing their job, right and well?
Can I infer that
CNAMES
Multiple Web Servers behind a single IP
subsequent resolution of a particular user request to the appropriate Web Server with the Host header
make sense only when you are using something like a Reverse Proxy e.g. 1 machine interfaces with the client and redirects user requests to the appropriate web server on separate machines all listening on the same port e.g. 80, each in the network behind the reverse proxy in which case you have ws1.example.com and ws2.exmple.com both be redirected to the reverse proxy example.com and this reverse proxy now forwards it to the appropriate host based on the Host header?
No DNS redirections
First an important terminology fix:
There are no "redirects" in the DNS. In your case, the DNS is just use to map a name to an IP. Sometimes, because of CNAME, a name is mapped to another name which is then mapped to an IP. It does not matter if there are intermediate steps like that, at the end a name maps to an IP (or there is a DNS resolution failure)
This also means that if the URL has a specific port, then that is not changed, the final IP will be queried over the port mentioned in the URL.
Redirections are an HTTP level feature: when querying a webserver for https://www.mygreatsite.example/foo it will reply with an HTTP return code of 301, 302, 303, 307 or 308 and giving you (the HTTP client, aka the browser) the new URL to go to.
HTTP virtual hosting
In the good old days, IP addresses were plenty. If you were hosting both www.site1.example and www.site2.example on the same physical box you could attach one different IP address to each.
Hence, in that specific case, in a way, the HTTP host header is useless, the mere fact of connecting either to 192.0.2.37 or 192.0.2.42 already lets you know which site you want.
In fact in HTTP/0.9 there was no host header, as there were no headers at all.
But then, with mass virtual hosting coming into play, and IPv4 addresses becoming scarce, you could not anymore attach one single IP address per site, since it was also a waste.
So you had, through the DNS, either directly or indirectly (CNAME records), both websites resolving to the same IP.
Hence when the HTTP client connected to the server, the server by default has no way to know which website do you want. That is why the HTTP host header filled by the client lets the server know which website you want to access, irrespective to its IP address, that was resolved earlier through the DNS.
By default HTTP uses port 80, so it is often not visible in the URLs.
Of course if you forced your clients to use http://www.site1.example:4569 on one side and http://www.anothersite2.com:9873 on another side, then you are right the host header would not be really needed.
Except that the plan falls down for many reasons:
Port numbers are not an infinite space either and many of them are already used typically for other things; so even if you extend this scheme at one point you could not attach new websites to the same IP
But more important than the previous technical point, for humans this will be a nightmare and many people will use forget the port number and then not coming to the appropriate website.
Hence typically it is not done like that, if you want to expose some given service over HTTP but in a non default port you typically install a reverse proxy in front of it. Or you do an HTTP redirection from http://www.coolpublicname.example/ to http://www.complicatedinternalname.example:9713, but then the client sees this naked truth.
HTTPS virtual hosting
In passing note that HTTPS added a level of complexity because the HTTPS webserver needs to send its certificate to the client, but since each website can have a different certificate it needs to know which website the client wants to use, which it could learn through the host HTTP header but then comes after the TLS handshake is finished, so in the early stage of the server sending a certificate this is not available yet.
So at the earliest times of HTTPS we were forced again to do IP-based virtual hosting and not name-based virtual hosting like it was possible in pure HTTP thanks to the host header.
The solution was found with a TLS extension, the Server Name Indication (SNI), something that the client sends early to the server and gives the website name, so that the server can send the appropriate certificate, and hence we are back in business in the name-based case where you can theoretically have an infinite number of names resolving to the same IP for them to be served by one given webserver.

Want to have app (Server:Port) to have friendly alias - Understanding Host Alias / DNS / A Record / CNAME

I am trying to get my head around Windows, Networks and Domains.
I currently have a server - svr. This is on my domain companyname.co.uk
I can connect to server and ping both svr and svr.companyname.co.uk.
On this server I have a number of applications with web access; TeamCity, Octopus etc. We currently connect to them by browsing to svr:xxxx where xxxx is the port of the web app host (http://svr:9090/ for TC)
I want to create friendly alias' - for example teamcity.companyname.co.uk would point at svr:9090, octopus.companyname.co.uk would point to svr:8090.
However, not being experienced in this area I can't seem to find relevant documents or sites that fully explain what I am looking for.
First, to make one thing clear: when you visit a web page like http://example.com, your web browser is actually making a request to example.com:80. This is done transparently because port 80 is the standard port for the HTTP protocol. As you know, you can request a non-standard port by appending it to the domain name in the URL: http://example.com:888/.
Unfortunately, you cannot have a domain name "alias" that somehow includes a non-standard port - your browser will always try to use port 80 if you don't specify a port.
One solution would be to use a proxy - nginx, apache, lighttpd, and others can all do this.
The idea is that you set up a proxy server that is listening on port 80 on your host. It waits for connections, then forwards those connections to a different server (on the same host, or on a different one) based on some rule. So, for example, you might have rules that look something like this:
IF host = teamcity.companyname.co.uk THEN forward to teamcity:9090
IF host = octopus.companyname.co.uk THEN forward to octopus:8090
The syntax for these rules vary widely between different proxy configurations, so this is just an example.
Note that this is not a redirect - the user's browser connects to teamcity.companyname.co.uk for all requests. It's the proxy that sends the request on to a different service and forwards any responses back to the client "behind the scenes".
These proxy configurations can get quite complex. For example, what if your teamcity application serves a page with a link on it that points to http://teamcity:9090/path/to/page? The user's browser is going to fail if they click on that link. Fortunately, proxies can be configured to rewrite URLs like this on the fly. You'll need to do some research to tailor this solution to your situation.

Resources