1

Example: I have two URLs

https:// www.abc.net  => maps to https://192.168.0.100:5000
https:// www.def.net  => maps to https://192.168.0.100:5001

Both servers running on the same Windows 10 PCs.

May I know how can I achieve that?

1 Answer 1

3

Port forwarding is forwarding traffic to a host based on specific ports. No additional information is used for this routing (i.e. any "destination" URLs). For routing specific URLs to particular local services, you'll likely want a reverse proxy.

In short, a reverse proxy takes requests from the Internet and forwards them to servers in an internal network. Importantly, it can often do this based on a particular URL received.

Software

For setting up a reverse proxy, two common solutions that would likely suit your needs are Apache and Nginx. Both are open source web servers and both can be configured to act as reverse proxies (via Apache virtual hosts or Nginx server blocks, respectively).

Windows builds of Apache with SSL are available from Apache Lounge and Windows builds of Nginx (which also support SSL) are directly available from Nginx.

Caveats

One thing to consider about a reverse proxy is that communications between a client and a local service may be limited by what the reverse proxy itself can pass.

In some cases, it could be preferable (or may even be necessary) to make a direct link between the client and a local service. For instance, assuming a router was mapping ports 5000 and 5001 to an internal host (e.g. 192.168.0.100) and that example.com and example.net were pointed to that router, those ports/services would likely be externally available as e.g. example.com:5000 and example.net:5001.

The basic downside to this is approach is that DNS doesn't use port information, so example.net:5000 and example.com:5001 would also map to the same services. However, for some types of communication, this might be the only option.


Reverse Proxy Example (Overview)

Assuming you decide to use Apache or Nginx as reverse proxy, while the individual configuration steps may be different, the basics are roughly the same:

  1. Install your preferred solution (e.g. either Apache or Nginx).
  2. Perform some basic configuration (so that it can respond to HTTP requests).
  3. Enable/configure any appropriate proxy features (as needed).
  4. Configure SSL support (since it appears you wish to respond to HTTPS URLs, based on your original question).
  5. Use virtual hosts (Apache) or server blocks (Nginx) to create hosts for the domains you wish to proxy data for, then configure those hosts to pass data between a client and the desired local service.

While the example below only covers using Apache as a reverse proxy, for Nginx, the steps outlined above are generally available on the web.


Reverse Proxy Example (Apache)

Assumptions

Below is a bare-bones example of how to setup Apache from scratch as reverse proxy on Windows. Note that it isn't intended to address any of the finer points of general Apache, SSL or reverse proxy configuration beyond sending requests from basic URL A to local service B.

It also assumes that:

  • The reverse proxy (i.e. Apache) is being installed on the same local server as the current services (ex. 192.168.0.100), outside of any virtual machine.

  • There are no services running on port 80 (HTTP) or 443 (HTTPS) on that host.

  • DNS is already set up correctly for any domains (e.g. example.com and example.net already point to the appropriate router/local network).

  • SSL certificates and keys are available for the domains you wish to proxy.

  • The local services you wish to proxy to are not using HTTPS (SSL) themselves.

  • Port forwarding is already set up correctly (i.e. ports 5000 and 5001 are mapped to 192.168.0.100). Note that for this example, ports 80 and 443 will also need to be mapped to the host with the reverse proxy (again, ex. 192.168.0.100).

Installation

  1. Download Apache from Apache Lounge and extract it. For this example, place the folder labeled Apache24 into C:\ on your local server (i.e C:\Apache24 on 192.168.0.100).

    Apache being built as 32-bit (ex. httpd-2.4.43-win32-VS16.zip) or 64-bit (ex. httpd-2.4.43-win64-VS16.zip) doesn't matter in this instance, so you can choose either one.

  2. Download the matching Microsoft Visual C++ Redistributable for Visual Studio 2015-2019 from the same page (either vc_redist_x86 for httpd-2.4.43-win32-VS16.zip or vc_redist_x64 for httpd-2.4.43-win64-VS16.zip). Double-click the executable to install it.

    If the installer displays the option to "Repair" an existing redistributable installation, you can safely cancel the installation entirely, as you already have an appropriate version of that redistributable installed.

  3. It is possible to install Apache as a service in Windows by running httpd -k install -n "Apache2.4" from the command line (httpd.exe is located under ex. C:\Apache24\bin). If you decide to do this, use an administrative command prompt and do not use a name for the service other than Apache2.4.

Configuration (Overview)

  • When editing any configuration file for Apache, you should use a plain text editor such as Windows Notepad or a third-party editor like Notepad++.

  • In the context of the steps given below, "uncomment" means to remove any leading # sign in front of one or more lines in a configuration file and "comment out" means to add a leading # sign in front of one or more lines in a configuration file:

    # This line is commented out
    This line is uncommented
    
  • In the individual configuration examples below, [...] is just an place holder intended to indicate "more irrelevant stuff here" (i.e. it doesn't actually go in the configuration file).

  • The majority of the configuration steps listed below are done in httpd.conf (ex. C:\Apache24\conf\httpd.conf), as it is the main configuration file for Apache.

  • For general SSL support and implementing the virtual hosts needed for a reverse proxy setup, there are changes that need to be made in httpd-ssl.conf (ex. C:\Apache24\conf\extra\httpd-ssl.conf) and httpd-vhosts.conf (ex. C:\Apache24\conf\extra\httpd-vhosts.conf) as well.

  • Configuration files need to be saved and Apache restarted (assuming it is running) for any configuration changes to take effect.

HTTP Configuration

Apache is already set up for handling basic HTTP requests out of the box, especially when placed in C:\Apache24 (the default directory the Apache Lounge version of Apache assumes it resides in). However, a warning will be emitted if the default ServerName directive in httpd.conf isn't uncommented. So make the following change:

ex. httpd.conf

[...]
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName www.example.com:80

For this example, the value of this ServerName directive doesn't matter, as long as it isn't one of the domains you wish to proxy (i.e. leaving it www.example.com:80 is fine).

Enabling Proxy Modules

Apache comes with a number of optional modules which enable additional features in Apache, such as the ability to proxy incoming requests to local services. These "extra" modules are listed in httpd.conf but are typically disabled (commented out) by default.

You don't mention the services you are attempting to proxy, but you should probably enable at least mod_proxy, mod_proxy_html, mod_proxy_http and mod_xml2enc in httpd.conf by uncommenting them like so:

ex. httpd.conf

[...]
LoadModule proxy_module modules/mod_proxy.so 
[...]
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_http_module modules/mod_proxy_http.so
[...]
LoadModule xml2enc_module modules/mod_xml2enc.so

mod_proxy is a "base" module that other proxy modules rely on, so it should always be uncommented. mod_proxy_html and mod_proxy_http should allow most web pages to be proxied successfully and mod_xml2enc helps ensure non-ASCII characters in proxied pages are displayed correctly.

SSL Certificates (Overview)

  • Please note that the instruction below assume that you have an existing self-signed SSL certificate and matching key specifically for www.example.com (as in the actual domain www.example.com, not merely as a documentation placeholder). These aren't directly used for proxying, but are required when including the default Apache httpd-ssl.conf file (unless additional configuration is done to that file, which is mostly skipped here).

  • If you do not have these files, I would suggest using this website to generate them. It only takes a moment and the domain in the link currently defaults to www.example.com. All you should need to do is click the button marked Generate and then use the resulting links to download the appropriate .cert and .key files (e.g. 12345678-www.example.com.cert and 12345678-www.example.com.key).

  • If you want to generate a self-signed certificate locally, SLProWeb offers Windows builds of OpenSSL that can be used from the command line, but those steps aren't covered here.

  • If you need free SSL certificates for the domain names you wish to proxy (these certificates are used later in the "virtual hosts" section of this example), I might suggest looking at ZeroSSL to obtain certificates from Let's Encrypt. They only last 3 months, but can be renewed indefinitely at no charge. Plus, ZeroSSL offers a simple, fairly easy-to-use command line client for obtaining/renewing Let's Encrypt certificates.

  • Be aware that it is important not to use encrypted SSL key files on Windows with Apache. Apache does not support SSL passphrases on Win32. If any of your SSL key files are encrypted with a passphrase, you must use OpenSSL to remove that passphrase before using it with Apache on Windows.

SSL (HTTPS) Configuration

  1. To enable SSL support in Apache, enable the mod_ssl module in httpd.conf by uncommenting it. For this example, you will also need to enable (uncomment) mod_socache_shmcb:

    ex. httpd.conf

    [...]
    LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
    #LoadModule speling_module modules/mod_speling.so
    LoadModule ssl_module modules/mod_ssl.so
    [...]
    
  2. For expediency, we will also include the default Apache SSL configuration file (httpd-ssl.conf). To do this, uncomment the following line near the end of httpd.conf:

    ex. httpd.conf

    # Secure (SSL/TLS) connections
    Include conf/extra/httpd-ssl.conf
    
  3. Create one (or more) folders to hold your www.example.com SSL certificate and key file. For this example, these folders should be under C:\Apache24. Place the appropriate files in the folder(s) you created.

  4. Open httpd-ssl.conf (ex. C:\Apache24\conf\extra\httpd-ssl.conf). Look for the line SSLPassPhraseDialog builtin and disable it (comment it out):

    ex. httpd-ssl.conf

    [...]
    #   Pass Phrase Dialog:
    #   Configure the pass phrase gathering process.
    #   The filtering dialog program (`builtin' is an internal
    #   terminal dialog) has to provide the pass phrase on stdout.
    #SSLPassPhraseDialog  builtin
    
  5. Further down in httpd-ssl.conf, look for the SSLCertificateFile and SSLCertificateKeyFile directives and change the paths after them to point to your www.example.com certificate and key files (wherever you placed them in Step 3, above):

    ex. httpd-ssl.conf

    [...]
    SSLCertificateFile "${SRVROOT}/path/to/12345678-www.example.com.cert"
    [...]
    SSLCertificateKeyFile "${SRVROOT}/path/to/12345678-www.example.com.key"
    [...]
    

Testing (Preliminary)

You should have a working, SSL enabled Apache server at this point (though not a reverse proxy just yet). To test this:

  • Save any changes you made to httpd.conf and httpd-ssl.conf (if you haven't already).

  • Navigate to your Apache bin directory (ex. C:\Apache24\bin).

  • Open a command window in that directory (ex. Shift + Right-Click a blank area in Explorer and choose the option to Open Command Prompt Here).

  • Run httpd.exe:

    Running httpd.exe - screenshot

  • This command window should remain open without any additional errors or warnings and without returning to the command line (e.g. C:\Apache24\bin>).

  • Assuming this is the case, you should be able to enter e.g. http://192.168.0.100 and https://192.168.0.100 into your browser and get a white page that states It works!.

  • Assuming your DNS is configured properly and you have port forwarded ports 80 and 443 to ex. http://192.168.0.100, using the HTTP and HTTPS versions of abc.net and def.net should yield the same page.

  • For SSL connections (ex. https://192.168.0.100), your browser may warn you that the certificate name doesn't match and/or that the certificate is self-signed. In this instance, it is safe to ignore any warnings and proceed with the connection.

Testing (Issues)

  • If any errors or warnings are displayed at the command line, fix them before proceeding.

  • If httpd.exe immediately stops (goes back to the command line) without any additional output, check the Apache error.log (ex. C:\Apache24\logs\error.log) for any issues e.g. with your SSL configuration.

  • If you cannot reach ex. https://192.168.0.100, ensure that any firewall on that host isn't blocking web traffic and that ports 80 and 443 are forwarded correctly to that host.

  • In some rarer cases, using ex. abc.net and def.net may not be possible without additional considerations or steps. This could be due to a router not supporting hairpinning (NAT Loopback) or worse, an ISP having Carrier-Grade NAT (CGNAT) or actively blocking ports.

  • Hairpinning issues can be bypassed by accessing ex. abc.net and def.net from a device not connected to your local network (e.g. a smartphone connected to a carrier's network).

  • CGNAT or similar may require a server completely outside your local network to act as an additional proxy to your network and isn't covered here.

Virtual Host (Reverse Proxy) Configuration

  1. After testing Apache (above), close the command window for httpd.exe to stop Apache.

  2. Reopen httpd.conf (ex. C:\Apache24\conf\httpd.conf) and enable the default Apache virtual hosts configuration file (httpd-vhosts.conf) by uncommenting the following line:

    ex. httpd.conf

    # Virtual hosts
    Include conf/extra/httpd-vhosts.conf
    
  3. Next, open httpd-vhosts.conf (ex. C:\Apache24\conf\extra\httpd-vhosts.conf) and comment out the existing virtual host example entries:

    ex. httpd-vhosts.conf

    [...]
    #<VirtualHost *:80>
         #ServerAdmin [email protected]
         #DocumentRoot "${SRVROOT}/docs/dummy-host.example.com"
         #ServerName dummy-host.example.com
         #ServerAlias www.dummy-host.example.com
         #ErrorLog "logs/dummy-host.example.com-error.log"
         #CustomLog "logs/dummy-host.example.com-access.log" common
    #</VirtualHost>
    
    #<VirtualHost *:80>
        #ServerAdmin [email protected]
        #DocumentRoot "${SRVROOT}/docs/dummy-host2.example.com"
        #ServerName dummy-host2.example.com
        #ErrorLog "logs/dummy-host2.example.com-error.log"
        #CustomLog "logs/dummy-host2.example.com-access.log" common
    #</VirtualHost>
    
  4. Add the following example virtual hosts to the end of httpd-vhosts.conf:

    ex. httpd-vhosts.conf

    # Redirect HTTP to HTTPS for http://example.com
    <VirtualHost *:80>
    
        ServerName example.com
        ServerAlias www.example.com
    
        Redirect permanent / https://example.com/
    
    </VirtualHost>
    
    # Redirect HTTP to HTTPS for http://example.net
    <VirtualHost *:80>
    
        ServerName example.net
        ServerAlias www.example.net
    
        Redirect permanent / https://example.net/
    
    </VirtualHost>
    
    # Redirect HTTPS requests for https://example.com to ex. 192.168.0.100:5000
    <VirtualHost *:443>
    
        ServerName example.com
        ServerAlias www.example.com
    
        SSLEngine on
        SSLOptions +StrictRequire
    
        SSLCertificateFile "${SRVROOT}/path/to/www.example.com.crt"
        SSLCertificateKeyFile "${SRVROOT}/path/to/www.example.com.key"
    
        # Required by first virtual SSL host
        #SSLProtocol TLSv1
    
        #ProxyPass / http://192.168.0.100:5000/
        #ProxyPassReverse / http://192.168.0.100:5000/
    
        # Localhost
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000/
    
    </VirtualHost>
    
    # Redirect HTTPS requests for https://example.net to ex. 192.168.0.100:5001
    <VirtualHost *:443>
    
        ServerName example.net
        ServerAlias www.example.net
    
        SSLEngine on
        SSLOptions +StrictRequire
    
        SSLCertificateFile "${SRVROOT}/path/to/www.example.net.crt"
        SSLCertificateKeyFile "${SRVROOT}/path/to/www.example.net.key"
    
        # Required by first virtual SSL host
        #SSLProtocol TLSv1
    
        #ProxyPass / http://192.168.0.100:5001/
        #ProxyPassReverse / http://192.168.0.100:5001/
    
        # Localhost
        ProxyPass / http://127.0.0.1:5001/
        ProxyPassReverse / http://127.0.0.1:5001/
    
    #</VirtualHost>
    
  5. Modify this updated example for your needs. In particular:

    • Unlike in httpd.conf and httpd-ssl.conf, substitute your actual domains (e.g. abc.net and def.net) for example.com and example.net (e.g. just do a simple search/replace).

    • Change the SSLCertificateFile and SSLCertificateKeyFile directives to point to the appropriate SSL certificate and key files for each of your domains (again, ex. abc.net and def.net). This example assumes you are dropping them in roughly the same folder(s) as your actual www.example.com certificate and key files from the prior "SSL" section (above).

    • While these examples omit per-host logging for space, you can add logging directives to any of the virtual hosts above if you wish.

  6. Save httpd-vhosts.conf after making the necessary changes above.

While Apache is running, your services on 192.168.0.100:5000 and 192.168.0.100:5001 should now be returned by either the HTTP or HTTPS versions of abc.net and def.net, respectively (with or without the www prefix, assuming the non-www versions are set in DNS).

1
  • outstanding answer!
    – Dima Dz
    Jan 6 at 18:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .