1

Sorry, I have mostly worked with NGINX so far. I would like to use apache 2 (on a host) to forward https and http traffic to several websites running on VirtualBox VM's. Each VM has several web sites or apps, all with little traffic (mostly bots anyway), on or behind nginx servers/reverse proxies. My router only allows a few ports to the host (80, 8080, 443) and the host firewall is also limited to a few applications (currently VirtualBox for example). I would prefer not to open more ports than 80(80) and 443.

How can I do this in a safe way? In principle the idea is in the conf below, but is this enough? Should I issue commandline commands? (How)Can it be made safer? Are other directives required?

httpd.conf:

<IfDefine SERVER_APP_HAS_DEFAULT_PORTS>
    Listen 8080
</IfDefine>
<IfDefine !SERVER_APP_HAS_DEFAULT_PORTS>
    Listen 80
</IfDefine>

LoadModule mpm_prefork_module libexec/apache2/mod_mpm_prefork.so
LoadModule authn_file_module libexec/apache2/mod_authn_file.so
LoadModule authn_core_module libexec/apache2/mod_authn_core.so
LoadModule authz_host_module libexec/apache2/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache2/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache2/mod_authz_user.so
LoadModule authz_core_module libexec/apache2/mod_authz_core.so
LoadModule access_compat_module libexec/apache2/mod_access_compat.so
LoadModule auth_basic_module libexec/apache2/mod_auth_basic.so
LoadModule reqtimeout_module libexec/apache2/mod_reqtimeout.so
LoadModule filter_module libexec/apache2/mod_filter.so
LoadModule mime_module libexec/apache2/mod_mime.so
LoadModule log_config_module libexec/apache2/mod_log_config.so
LoadModule env_module libexec/apache2/mod_env.so
LoadModule headers_module libexec/apache2/mod_headers.so
LoadModule setenvif_module libexec/apache2/mod_setenvif.so
LoadModule version_module libexec/apache2/mod_version.so
LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
LoadModule slotmem_shm_module libexec/apache2/mod_slotmem_shm.so
LoadModule unixd_module libexec/apache2/mod_unixd.so
LoadModule status_module libexec/apache2/mod_status.so
LoadModule autoindex_module libexec/apache2/mod_autoindex.so
<IfModule !mpm_prefork_module>
    #LoadModule cgid_module libexec/apache2/mod_cgid.so
</IfModule>
<IfModule mpm_prefork_module>
    #LoadModule cgi_module libexec/apache2/mod_cgi.so
</IfModule>
LoadModule negotiation_module libexec/apache2/mod_negotiation.so
LoadModule dir_module libexec/apache2/mod_dir.so
LoadModule alias_module libexec/apache2/mod_alias.so
LoadModule hfs_apple_module libexec/apache2/mod_hfs_apple.so

<IfModule unixd_module>
User _www
Group _www

</IfModule>

ServerAdmin you@example.com

ServerName localhost

<Directory />
    AllowOverride none
    Require all denied
</Directory>

<FilesMatch "^\.([Hh][Tt]|[Dd][Ss]_[Ss])">
    Require all denied
</FilesMatch>

<Files "rsrc">
    Require all denied
</Files>
<DirectoryMatch ".*\.\.namedfork">
    Require all denied
</DirectoryMatch>

ErrorLog "/private/var/log/apache2/error_log"

LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog "/private/var/log/apache2/access_log" common

</IfModule>

<IfModule alias_module>
    ScriptAliasMatch ^/cgi-bin/((?!(?i:webobjects)).*$) "/Library/WebServer/CGI-Executables/$1"

</IfModule>

<IfModule cgid_module>
    #Scriptsock cgisock
</IfModule>

<IfModule headers_module>
    RequestHeader unset Proxy early
</IfModule>

<IfModule mime_module>
    TypesConfig /private/etc/apache2/mime.types

    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

</IfModule>


TraceEnable off

Include /private/etc/apache2/extra/httpd-mpm.conf

Include /private/etc/apache2/extra/httpd-vhosts.conf

<IfModule proxy_html_module>
Include /private/etc/apache2/extra/proxy-html.conf
</IfModule>

<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

Include /private/etc/apache2/other/*.conf

extra/httpd-vhosts.conf

ProxyRequests Off

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass        "/" "http://localhost:8082/"
    ProxyPassReverse "/" "http://localhost:8082/"
    ServerName abc.de
</VirtualHost>

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass        "/" "http://localhost:8081/"
    ProxyPassReverse "/" "http://localhost:8081/"
    ServerName fgh.ij
</VirtualHost>

I also read I need to enable apache2 modules, using LoadModule statements (on OSX): which are necessary for safe forward proxying?

I think i would also like to make use of this: https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html It seems from the documentation like the proxied (internet, bot) clients are not identifiable by the web servers, because they are identifying as the proxy server. Of course, my websites need to know who is visiting.

JuliusBaer
  • 23
  • 5

1 Answers1

1

Your configuration looks mostly alright:

  • Since you are not using Apache as a forward proxy (you don't have the ProxyRequests directive), you don't need to worry about proxy access rights. Your Apache is configured as a reverse proxy.
  • You don't mention which distribution you are using, but usually the en2mod and dis2mod commands are shortcuts for creating symbolic links between the /etc/apache2/mods-available and /etc/apache2/mods-enabled. The files from the latter directory are included from the main config file.
  • mod_remoteip is needed if your Apache2 server receives requests from another reverse proxy. This is not your case: your Apache2 sends requests to the upstream servers. In this case you need to look at the ProxyAddHeaders directive, which is 'on' by default.

Edit: You seem to confuse the concepts of forward and reverse proxy:

  • If you want the clients to request any URL through your Apache2 server (e.g. use your server to access http://google.com), you need a forward proxy.

  • If you want your server to transparently forward requests to a preconfigured set of servers, you need a reverse proxy. Basically a reverse proxy mirrors the content of a limited set of other servers as its own.

Piotr P. Karwasz
  • 5,748
  • 2
  • 11
  • 21
  • 1. You don't need `ProxyRequests` for your usage. You are configuring a reverse proxy. 2. On Linux distributions the files in `/etc/apache2/mods-available` mostly contain just a `LoadModule` directive. You need `LoadModule proxy_module /path/to/module`, which is probably already in you config file. – Piotr P. Karwasz Feb 29 '20 at 08:13
  • Oh I see, you may be right. Forward proxies are for https over http tunnelling? I guess I should have read [this](https://en.wikipedia.org/wiki/Proxy_server#Reverse_proxies) before [this](https://httpd.apache.org/docs/trunk/vhosts/examples.html#proxy). Although it somewhat eludes me. Care to explain? – JuliusBaer Feb 29 '20 at 08:22
  • A forward proxy is used, if you can't access the web directly (e.g. a restrictive firewall, which blocks connection to port `80`) or for caching reasons. You configure it in your browser, which will send all the requests to the proxy server, instead of the appropriate web servers. – Piotr P. Karwasz Feb 29 '20 at 08:24
  • Right, but for for example apps (on app servers), the reverse proxy does the "whole" web serving, while here it only needs to route traffic. Isn't that a sticking point? – JuliusBaer Feb 29 '20 at 08:26
  • Apps are regular web-servers, although usually running on non-standard ports (so accessible through e.g. `http://example.com:8080/app`). A reverse proxy gives each of them a new URL with standard port (`http://example.com/path/to/app`). – Piotr P. Karwasz Feb 29 '20 at 08:31
  • OK, I learn every day. [Apparently](https://stackoverflow.com/questions/936197/what-is-the-difference-between-application-server-and-web-server) web servers are good for serving static content. In Nginx there are usually a lot of statements for whatever. Those aren't in app servers, that are straight to the point. I'm not sure I should delete the question. Is reverse proxying altogether different? I started [here](https://httpd.apache.org/docs/trunk/vhosts/examples.html#proxy) and this fits. – JuliusBaer Feb 29 '20 at 08:43
  • Edit the mentioning, that you meant a reverse proxy instead. You configure a reverse proxy with the `ProxyPass*` directives. That is already done. – Piotr P. Karwasz Feb 29 '20 at 08:47
  • 1
    The warning [here](https://httpd.apache.org/docs/current/mod/mod_proxy.html) only applies to forward proxying. – JuliusBaer Feb 29 '20 at 10:12
  • I am forwarding port 80 to port 192.168.178.13:8080 (the host). There I have the above httpd configuration. httpd is permitted on the host firewall. http://127.0.0.1:8081 works. http://192.168.178.13 gives 403 forbidden, the external IP address and the domain name don't respond. What am I doing wrong? `% sudo apachectl configtest` passes, turning off the host firewall doesn't change anything. – JuliusBaer Mar 05 '20 at 11:42
  • `AH01630: client denied by server configuration: /usr/htdocs` in the log when browsing to the domain name. But I only need the reverse proxy. – JuliusBaer Mar 05 '20 at 11:54
  • And, when I turn off the host firewall, the browser quickly loads nothing, while with the firewall on, it waits for some time(-out). – JuliusBaer Mar 05 '20 at 12:14
  • You might have another `` in the config, which catches requests to port `8080`. `apache2ctl -S` lists them all: your ``s are configured for port `80`. Replace the initial `` blocks with a simple `Listen 8080` and use the same port for the ``s – Piotr P. Karwasz Mar 05 '20 at 18:20