httpd Reverse Proxy - Centos 8 - apache

I am trying to setup a reverse proxy using Apache2 on a Centos 8 server.
I currently have nextcloud running on this apache server fine. This is hosted on the domain storage.domain.com.
I'd like to setup a reverse proxy for the domain proxy.domain.com to the port 8181.
My config currently exists in the /etc/httpd/conf.d directoy.
My reverse proxy file (proxyfile.conf)is as follows:
ServerName proxy.domain.com
<VirtualHost *:80>
ServerName proxy.domain.com
<Location />
ProxyPass http://127.0.0.1:8181/
ProxyPassReverse http://127.0.0.1:8181/
ProxyPreserveHost On
</Location>
</VirtualHost>
For reference, my nextcloud file (nextcloud.conf)is as follows:
<VirtualHost *:80>
DocumentRoot /var/www/nextcloud/
ServerName storage.domain.com
Redirect permanent / https://storage.domain.com
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000"
</IfModule>
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
RewriteEngine on
RewriteCond %{SERVER_NAME} =storage.domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
The issue currently is when I go to the domain proxy.domain.com is that it redirects me to storage.domain.com.
I was expecting the page at 127.0.0.1:8181 to load when visiting proxy.domain.com.
Any help would be greatly appreciated. Thank you!

Related

Set up an apache reverse proxy with SSL certs and multiple domains

I need help configuring Apache to act as a reverse proxy with https and multiple domains, such that www.myfirstdomain.com and www.myseconddomain.com both point to x.x.x.x and than the server will selectively forward to, let's say, x.x.x.x:2400 (myfirstdomain.com, http), x.x.x.x:2401 (myfirstdomain.com, https), x.x.x.x:2600 (myseconddomain.com, http) and x.x.x.x:2601 (mysecondomain.com, https).
I tried many options but in the end I got stuck because I issued more than 5 certs (renews) per week and also I couldn't make it work.
myfirstdomain.com and www.myfirstdomain.com (http and https) were configured as follows:
/etc/apache2/sites-available/000-default.conf :
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:2400/
ProxyPassReverse / http://127.0.0.1:2400/
</VirtualHost>
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:2401/
ProxyPassReverse / http://127.0.0.1:2401/
</VirtualHost>
<VirtualHost *:2400>
ServerName myfirstdomain.com
ServerAlias www.myfirstdomain.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/myfirstdomain/public
<Directory /var/www/html/myfirstdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =myfirstdomain.com
RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
RewriteCond %{SERVER_NAME} =www.myfirstdomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:2401>
ServerName myfirstdomain.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/myfirstdomain/public
<Directory /var/www/html/myfirstdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =myfirstdomain.com
RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Then I generated the certs with certbot --apache for both www and non-www and I had this file:
/etc/apache2/sites-available/000-default-le-ssl.conf:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:2401/
ProxyPassReverse / http://127.0.0.1:2401/
</VirtualHost>
<VirtualHost *:2401>
ServerName myfirstdomain.com
ServerAlias www.myfirstdomain.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/myfirstdomain/public
<Directory /var/www/html/myfirstdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
# Some rewrite rules in this file were disabled on your HTTPS site,
# because they have the potential to create redirection loops.
# RewriteCond %{SERVER_NAME} =myfirstdomain.com
# RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
# RewriteCond %{SERVER_NAME} =www.myfirstdomain.com
# RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
SSLCertificateFile /etc/letsencrypt/live/www.myfirstdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.myfirstdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
I also tried to regenerate the HTTPS certificates but it won't work. How do I do it?
First of all, remember that Apache listens on a range of ports, for instance 80 and 443.
Virtualhosts use the same ports (80 and 443) and Apache selects the correct folder using the domain name you use.
For example, myfirstdomain.com could display /var/www/html/myfirstdomain/public, but
if apache listens on port 80, it never match the rule for *:2400.
I haven't tryed this, but you could put ProxyPass and ProxyPassReverse in each virtual hosts and leave the port to :80 or :443.
When you call myfirstdomain.com:80, the rule on apache match and it executing proxing to another server.
See this answer.
LetsEncrypt create an ACME challenge (a file with a random string) that could be reachable from the internet. The Certification Server search this file, if exists the certificate is released; if not, it throw an error.
I don't remember the correct pathof the file, but you must verify:
can you reach "myfistdomain.com" from the internet?
an external server can reach "myfistdomain.com" ? (check dns name and port forwarding of your router
can you open the ACME challenge file?
can the server open the ACME challenge file?
On some Plesk installations acme files cannot be reacheable because Plesk adds some automatic rules.

Apache Reverse Proxy For Specific Subdomain

I'm have a an Apache HTTP server that has a reverse proxy to a tomcat server. However, I only want the reverse proxy to happen when the client uses the subdomain www. This is because I want to use other subdomains to point to other applications, such as email.
e.g. www.example.com will go display the apache tomcat webapp.
The way to do this, I presume, is to configure my DNS so that every subdomain I use will point to my server. Right now, in addition to www, that is server.example.com and posfixadmin.example.com. However, the issue is that all my subdomains end up pointing to tomcat.
So when I try to visit postfixadmin.example.com/setup.php to set up postfixadmin through its web setup, it ends up taking me to my tomcat webapp's 404.
Here is my virtualhost configuration:
<VirtualHost www.example.com:80>
ServerName http://www.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
<VirtualHost server.example.com:80>
ServerName server.example.com
DocumentRoot /var/www/html/
RewriteEngine on
RewriteCond %{SERVER_NAME} =server.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} {END,NE,R=permanent}
</VirtualHost>
<VirtualHost postfixadmin.example.com:80>
ServerName postfixadmin.example.com
DocumentRoot /var/www/postfixadmin/public
ErrorLog /var/log/httpd/postfixadmin_error.log
CustomLog /var/log/httpd/postfixadmin_access.log combined
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/postfixadmin/public>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
EDIT
It looks like the proxy conf file doesn't do anything (??). I decided to experiment around and change the first virtualhost servername to the following:
<VirtualHost *:80>
ServerName abcd.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
Then, I restarted and reloaded Apache...But for some reason, going to www.example.com STILL took me to the tomcat webapp! Does anyone know what drives this?
As to the DNS: I have set specific CNAME entries for each subdomain including www; all of them point back to the public IP of my server that houses my example.com domain (using # in my case - possible with most DNS, I think). There may be some different strategies on this, but I believe you're on the correct path based on what you've suggested in the question.
As to Apache configuration:
I believe that the http protocol does not need to be specified in the ServerName directive and that, generally, the domain need not appear inside the <VirtualHost>...</VirtualHost> tags.
I should mention that I am relatively unfamiliar with Tomcat but am assuming it is listening at 8080 on the localhost, in which case this should help.
I'm not 100% certain that that is all that is snarling you, but try trimming that ServerName back and doing like so, including the change to the VirtualHost open tag:
<VirtualHost *:80>
ServerName www.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
Your second <VirtualHost> probably requires similar changes, though it also seems that you are directing it to serve requests from the web/network which are coming in on port 8080 -- which I don't believe is your intent.
I think what you want is to also listen on port 80 from the web/network, but to follow these directives if addressed to server.example.com like so:
<VirtualHost *:80>
ServerName server.example.com
DocumentRoot /var/www/html/
RewriteEngine on
RewriteCond %{SERVER_NAME} =server.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} {END,NE,R=permanent}
</VirtualHost>
And finally, similar change to the opening <VirtualHost> tag on the final one:
<VirtualHost *:80>
ServerName postfixadmin.example.com
DocumentRoot /var/www/postfixadmin/public
ErrorLog /var/log/httpd/postfixadmin_error.log
CustomLog /var/log/httpd/postfixadmin_access.log combined
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/postfixadmin/public>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
Altogether, this seems more like what you're looking for:
<VirtualHost *:80>
ServerName www.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
<VirtualHost *:80>
ServerName server.example.com
DocumentRoot /var/www/html/
RewriteEngine on
RewriteCond %{SERVER_NAME} =server.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} {END,NE,R=permanent}
</VirtualHost>
<VirtualHost *:80>
ServerName postfixadmin.example.com
DocumentRoot /var/www/postfixadmin/public
ErrorLog /var/log/httpd/postfixadmin_error.log
CustomLog /var/log/httpd/postfixadmin_access.log combined
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/postfixadmin/public>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
I got it!
It turns out that the problem was in the ssl configuration file - the :443 ports were overlapping.
Thanks for the help!

Proxy pass an application from a different machine to an apache web server

I have three applications running, 2 on local machine/server where Apache is installed and 1 on a different machine/server.
I am using Apache2.4 on Ubuntu 18.04
application 1(yii) = 127.0.0.1:80
application 2(mantis bt) = 127.0.0.1:8080
application 3(yii) = 192.168.X.X:80
I want to configure my apache web server to host the three applications on https. I proxy pass both app2 and app3.
app2 = /app2 http://127.0.0.1:8080
app3 = /app3 http://192.168.X.X
app1 can be accessed successfully without error,
app2 and app3 can be accessed but .css, .js and other files cannot be found and error 404.
Note: I can access all three apps when not on proxy pass.
also it is possible to host the three apps and have a url like the following:
https://app1.example
https://app2.example
https://app2.example
I am new to apache. Please help me.
Configure apache virtual host as a below configuration
For app2
<Virtualhost *:80>
ServerName app2.domain.com
ServerAdmin youremail#email.com
ProxyPass http://127.0.0.1:8080/
ProxyPassReverse http://127.0.0.1:8080/
</Virtualhost *:80>
For app3
<Virtualhost *:80>
ServerName app3.domain.com
ServerAdmin youremail#email.com
ProxyPass http://192.168.X.X/
ProxyPassReverse http://192.168.X.X/
</Virtualhost *:80>
Create a separate virtual host for both domains.
After creating virtual host restart apache
service apache2 restart
It's working for me, I hope it will be worked for you and load .css, .js and other files.
If you want to redirect aap3 to https, then your final virtual host file will be like below configuration:
<Virtualhost *:80>
ServerName app2.domain.com
ServerAdmin youremail#email.com
ProxyPass http://127.0.0.1:8080/
ProxyPassReverse http://127.0.0.1:8080/
</Virtualhost *:80>
<Virtualhost *:80>
ServerName app3.domain.com
Redirect / https://app3.domain.com/
</Virtualhost *:80>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName app3.domain.com
ServerAdmin youremail#email.com
ProxyPass http://192.168.X.X/
ProxyPassReverse http://192.168.X.X/
Include /etc/letsencrypt/options-ssl-apache.conf
ServerAlias app3.domain.com
SSLCertificateFile /etc/letsencrypt/live/app3.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app3.domain.com/privkey.pem
</VirtualHost>
</IfModule>
Please check my config below:
DocumentRoot /var/www/html/app1
ErrorLog /var/log/httpd/app1_log
LogLevel debug
<Directory /var/www/html/app1>
AllowOverride none
Order allow,deny
Allow from all
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
</Directory>
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
</Proxy>
<Location /app2>
ProxyPass http://127.0.0.1:8080/login_page.php
ProxyPassReverse http://1127.0.0.1:8080/login_page.php
SetEnv proxy-sendchunks 1
</Location>
<Location /app3>
ProxyPass http://192.168.X.X/
ProxyPassReverse http://192.168.X.X/
SetEnv proxy-sendchunks 1
</Location>
<Location /static/>
ProxyPass !
</Location>
</VirtualHost>
<VirtualHost *:443>
SSL Configuration
</VirtualHost>

Apache reverse-proxy changes the url in the browser

Below is my configuration:
All HTTPS requests are redirected to port 8081 of apache
And in my configuration file of apache I am using below mentioned configuration
<VirtualHost *:8081>
ServerName www.servername.com
ServerAlias servername.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^.*_url_=(.*)
RewriteRule ^.*$ /make?url=%1 [B,L,P,S=1]
</Directory>
ProxyPreserveHost On
ProxyPass /make http://localhost:8084/
ProxyPassReverse /make http://localhost:8084/
</VirtualHost>
In which one more server is hosted on port 8084 which returns back the page.
Everything is working fine, apart from the url getting changed.
So if I am making a request as
https://www.servername.com?url=queryString
it returns the correct response as expected, but the url changes to
https://www.servername.com/make?url=queryString
Please help me in figuring out, that what parameter I am missing in my apache configuration in the proxy, which can help in avoiding the url getting changed.
Thanks

Configuring multiple websites on a single Apache instance

I am looking for a way to host multiple websites on a single server. Currently I have used reverse proxy to host two of the websites using the following method:
I have a php site in /var/www/html folder and a nodejs app running on localhost:3015. My apache2 config is like following:-
<VirtualHost *:80>
ServerName site1.example.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://localhost:3015/
ProxyPassReverse / http://localhost:3015/
ServerName site2.example.com
</VirtualHost>
Now I further want to host few old websites at:
site1.example.com/archives/2014, 13 and so on
site2.example.com/archives/2014, 13 and so on.
In case of site1.example.com I can use alias as the site hosted is a php site.
In the second case where I am using reverse proxy what will be the best way to host a php site.
Also, please suggest a way where new sites can be easily added and the old sites can be moved to archived folder. These site might be on django, ROR and so on.
Is this even possible?
This may not be quite what you are asking for, but give this a try. It's a variation on the Apache config I use in a dev VM, which is set up for wildcard domain hosting. I haven't tested this config specifically, but you should be able to tweak it to suit your needs.
This essentially tells Apache how to find sites such as:
site1.example.com => /var/www/html/site1/public_html
site2.example.com => /var/www/html/site1/public_html
2014.archive.site1.example.com => /var/www/html/site1/public_html/archives/2014
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
DirectoryIndex index.html index.php
RewriteEngine on
RewriteMap lowercase int:tolower
# *.example.com
RewriteCond ${lowercase:%{SERVER_NAME}} ^[a-zA-Z0-9-]+\.example\.com$
RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
RewriteRule ^([a-zA-Z0-9-]+)\.example\.com/(.*) /var/www/html/$1/public_html/$2
# *.archive.*.example.com
RewriteCond ${lowercase:%{SERVER_NAME}} ^[a-zA-Z0-9-]+\.archive\.[a-zA-Z0-9-]+\.example\.com$
RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
RewriteRule ^([a-zA-Z0-9-]+)\.archive\.([a-zA-Z0-9-]+)\.example\.com/(.*) /var/www/html/$2/public_html/archives/$1/$3
</VirtualHost>
If this isn't what you were asking for, let me know.
I finally figured out a way to do the same. What you need to do is host all the sites at different port:
site1 => 3015
site2 => 4015
site3 => 3014
site4 => 4014
and so on.
Now you can configure your default.conf in apache2 as following:
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass /archive/2014/ http://localhost:3014/
ProxyPassReverse /archive/2014/ http://localhost:3014/
ProxyPass / http://localhost:3015/
ProxyPassReverse / http://localhost:3015/
ServerName site1.example.com
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass /archive/2014/ http://localhost:4014/
ProxyPassReverse /archive/2014/ http://localhost:4014/
ProxyPass / http://localhost:4015/
ProxyPassReverse / http://localhost:4015/
ServerName site2.example.com
</VirtualHost>
This will work for sites on any platform, currently my site3 and site4 are php and site1 and site2 are node and django respectively. You might need to play with urls and links a little to make everything work perfectly.