nginx [engine x] is an HTTP and reverse proxy server, as well as a mail proxy server.

Installation

nginx (and libdaemon) can be installed with the Pakfire web interface or via the console:

pakfire install nginx libdaemon

Configuration

You will find the configuration files in /etc/nginx.

You can find a very good and detailed configuration manual on the official nginx homepage at: http://nginx.org/en/docs/.

Example 1: Reverse Proxy

This example will make nginx run as a SSL reverse proxy. This means that all services running behind the ipfire firewall do not have ssl enabled but if you are connecting to them from the internet SSL is enabled by the nginx reverse proxy: /etc/nginx/nginx.conf

server {
    listen       443 ssl;
      server_name  127.0.0.1;
      ssl                  on;
      ssl_certificate         /etc/ssl/certs/nginx.crt;
      ssl_certificate_key     /etc/ssl/private/nginx.key;
      ssl_session_timeout  10m;
      client_max_body_size 1000M;

      ssl_protocols             TLSv1.1 TLSv1.2 TLSv1;
      ssl_ciphers               ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:!ADH:!AECDH:!M$;
      ssl_prefer_server_ciphers on;
      ssl_session_cache         shared:SSL:10m;

        include sites/*.conf;
      }

I am only describing the server block here. For all other configurations please have look at the nginx documentation. For each service I created a config file under the directory sites. You will have to create this one by yourself and all config files need to have a .conf at the end.

/etc/nginx/sites/default.conf is my default configuration, where my web server is running.

location / {
 proxy_pass http://192.168.222.111:80;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 proxy_set_header X-Forwarded-Proto https;
 proxy_redirect http:// https://;
}

Example 2: Reverse Proxy for MS Exchange server

If your company use MS Exchange as an e-mail-server for security reasons it is recommended, that the http-services of MS Exchange are not in the first row and don't communicate directly with clients in the internet.

In this case it is a good idea, to use nginx as a reverse-proxy for OutlookWebAccess (OWA) and ActiveSync (sync mobile devices). And of course the ExchangeWebService (EWS) should only accessible from the intranet.

Put these lines for the Exchange locations in your standard nginx.conf into the 'ssl-server-section' and comment these four lines for the standard server www-root-location, if you don't need nginx as a web server:

server {
      listen      443 ssl;
...
#        location / {
#            root   html;
#            index  index.html index.htm;
#                   }
...
      location /owa {
   proxy_pass https://IP_OF_YOUR_EXCHANGE/owa;
                }
      location /Microsoft-Server-ActiveSync {
   proxy_pass https://IP_OF_YOUR_EXCHANGE/Microsoft-Server-ActiveSync;
          proxy_read_timeout=1500;
                }
            }
}

Reload nginx and surf from the RED net to https://ipfire/owa. You should see the OWA-Login-Site of your MS Exchange.

But the ssl-certificate comes from the nginx and not from the MS Exchange. Your reverse-proxy is working well!

Access to the ExchangeWebService under https://ipfire/ews should be forbidden!

Syncing your mobile devices should be working well.

If you have any trouble, look for nginx log files in /var/log/nginx.

Example 3: Managing ssl-certificates for all your sites by acme.sh and Let's Encrypt

Your nginx is working as a reverse proxy for a couple of websites with different domains behind. User who surf to your sites by ssl see the nginx delivered ssl-certificate . In most cases this is self-signed and would be marked by browsers as unsecured. You need for every of your hosted domains a secure ssl-certificate and nginx should deliver it. The solution is a little script acme.sh and Let's Encrypt as CertAuthority!

First log in to your IPFire as root by ssh and load the script on your IPFire:

curl https://get.acme.sh | sh

The script makes a new directory /root/.acme and load the required files into this directory. In addition, a cronjob is created, which is responsible for the regular renewal of the certificates.This is important because Let's Encrypt certs are only valid for 3 months.

Run now the script for every domain you host. It is important, that your nginx is accessible on port 80, because the script is loading some test pattern to your nginx-www-root and Let's Encrypt compare this by surfing to http://yourdomain.tld!

acme.sh --issue -d yourdomain_1.tld -w /usr/share/nginx/html
acme.sh --issue -d yourdomain_2.tld -w /usr/share/nginx/html
...

If everything okey, your certs are now in /root/.acme/yourdomain_x.tld/ If you have some trouble, run acme.sh with --debug as an additional flag.

Now open /etc/nginx/nginx.conf and point the path to your new Let's Encrypt cert files for every domain you have:

server {
    listen 443 ssl;
    sever_name yourdomain_1.tld;
    ssl_certificate     /root/.acme/yourdomain_1.tld/yourdomain_1.tld.cer;
    ssl_certificate_key /root/.acme/yourdomain_1.tld/yourdomain_1.tld.key;
    ...
    }
server {
    listen 443 ssl;
    sever_name yourdomain_2.tld;
    ssl_certificate     /root/.acme/yourdomain_1.tld/yourdomain_2.tld.cer;
    ssl_certificate_key /root/.acme/yourdomain_1.tld/yourdomain_2.tld.key;
    ...
    }
...

Reload your nginx by typing:

/etc/init.d/nginx reload

and surf to your website with https://. You should now get a green certificate, signed by Let's Encrypt for your domain. If you have any trouble, look for /var/log/nginx/error.log.

Many thanks to Neilpang for write this nice script!

Source:

Example 4: ReverseProxy with Nextcloud/Owncloud and additional virtual domain on different web servers

This example extends the above example by the following things:

The ReverseProxy (nginx) should manage the requests for more than one domain on more than one web server. Several domains are hosted as virtual domains by only one web server. Thats why the server_name-directive is very important.

Furthermore in this example a Nextcloud/Owncloud shall run on one of the web servers. The cloud notices that it is running behind a reverse proxy. This is therefore where reworking is necessary.

The communication between the ReverseProxy and the web servers behind should also be ssl encrypted. This requires that the Acme Challenge of Let'sEncrypt is negotiated on the ReverseProxy, because this can only be done unencrypted We will use the property of nginx, that in nginx.conf the declarations are applied in the order from top to bottom. In other words, if one declaration is true, all declarations behind it are discarded. So it is possible to pre-filter the requests for /.well-known/acme-challenge/ (for handle them directly on the reverse proxy) and forward all other requests to the apaches behind.

It is important that not only requests for /.well-known/ are filtered, but also the complete path to the challenges. This is because Nextcloud/Owncloud also handles the caldav/cardav connections by default via the /.well-known/cardav or /.well-known/caldav directory.

Here is the scheme:

Internet---ssl--->nginx----ssl--->apache1----->domain1
                     I                  I----->domain2     
                     I-----ssl--->apache2---->domain3

This is the commented nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http{

gzip on;

  # if you have many server{}-declarations, 32 is not enough ---> 64
  server_names_hash_bucket_size 64;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  # Common TLS Config

    ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        ssl_protocols TLSv1.2 TLSv1.3;

server {        

    listen 80 default_server;

# Directory for LetsEncrypt for all following domain 
# this directory will not be rewritten to https!

  location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;
    #just for testing switch on the autoindex, so that you can see, 
    # if there is access to the directory at all
#        autoindex on;
        }

  # redirects all over http requests to https requests

  location ^~ / {
        rewrite ^ https://$host$request_uri? permanent;
  }
}

######## domain1.de

  server {
    # replace with your domain
    server_name domain1.de;

    listen 443 ssl http2;

    ssl_certificate      /root/.acme.sh/domain1.de/domain1.de.cer;
    ssl_certificate_key  /root/.acme.sh/domain1.de/domain1.de.key;

    # maximum 3GB Upload File; change to fit your needs
    client_max_body_size 3G;

    location / {
      # enable ssl for the internal connection between ReverseProxy and web server
      #  but disable certificate test, so that also self-signed are accepted
      proxy_ssl_verify off;
      proxy_pass https://IP-Adresse_apache1;
      # set proper x-forwarded-headers
      proxy_set_header 'X-Forwarded-Host' domain1.de;
      proxy_set_header 'X-Forwarded-Proto' https;
      proxy_set_header Host $host;
      # -For and -IP:
      # see https://stackoverflow.com/questions/19366090/what-is-the-difference-between-x-forwarded-for-and-x-forwarded-ip
      proxy_set_header 'X-Forwarded-For' $remote_addr;
      proxy_set_header 'X-Forwarded-IP' $remote_addr;
      proxy_http_version 1.1;
    }
  }

######## domain2.de

  server {
    # replace with your domain
    server_name domain2.de;

    listen 443 ssl http2;

    ssl_certificate      /root/.acme.sh/domain2.de/domain2.de.cer;
    ssl_certificate_key  /root/.acme.sh/domain2.de/domain2.de.key;

    # maximum 3GB Upload File; change to fit your needs
    client_max_body_size 3G;

    location / {
      # enable ssl for the internal connection between ReverseProxy and web server
      #  but disable certificate test, so that also self-signed are accepted
      proxy_ssl_verify off;
      proxy_pass https://IP-Adresse_apache1;
      # set proper x-forwarded-headers
      proxy_set_header 'X-Forwarded-Host' domain2.de;
      proxy_set_header 'X-Forwarded-Proto' https;
      proxy_set_header Host $host;
      # -For and -IP:
      # see https://stackoverflow.com/questions/19366090/what-is-the-difference-between-x-forwarded-for-and-x-forwarded-ip
      proxy_set_header 'X-Forwarded-For' $remote_addr;
      proxy_set_header 'X-Forwarded-IP' $remote_addr;
      proxy_http_version 1.1;
    }
  }

######## domain3.de

  server {
    # replace with your domain
    server_name www.domain3.de;

    listen 443 ssl http2;

    ssl_certificate      /root/.acme.sh/domain3.de/domain3.de.cer;
    ssl_certificate_key  /root/.acme.sh/domain3.de/domain3.de.key;

    # maximum 3GB Upload File; change to fit your needs
    client_max_body_size 3G;

    location / {
      # enable ssl for the internal connection between ReverseProxy and web server 
      # but disable certificate test to accept self-signed ones as well
      proxy_ssl_verify off;
      proxy_pass https://IP-Adresse_apache2;
      # set proper x-forwarded-headers
      proxy_set_header 'X-Forwarded-Host' domain3.de;
      proxy_set_header 'X-Forwarded-Proto' https;
      proxy_set_header Host $host;
      # -For and -IP:
      # see https://stackoverflow.com/questions/19366090/what-is-the-difference-between-x-forwarded-for-and-x-forwarded-ip
      proxy_set_header 'X-Forwarded-For' $remote_addr;
      proxy_set_header 'X-Forwarded-IP' $remote_addr;
      proxy_http_version 1.1;
    }
  }
}

For Nextcloud/Owncloud, add the following lines to config.php (192.168.111.1 is the IP of the ReverseProxy, please use your own):

 'trusted_proxies' => 
  array (
    0 => '192.168.111.1',
  ),
  'overwritecondaddr' => '^192\\.168\\.111\\.1$',
  'overwriteprotocol' => 'https',
 'overwrite.cli.url' => 'https://domain1.de',