Apache VirtualHost subdomain forwarding to Mercurial cgi script - apache

I need to hook up my Mercurial server cgi script through an Apache VirtualHost subdomain along with authorization.
My apache is running on 80 and 91.
Apache is serving Mercurial through
C:\wamp\bin\apache\Apache2.2.21\cgi-bin\hgweb.cgi
and is accessable through
http://my.com/cgi-bin/hgweb.cgi
and
http://localhost/cgi-bin/hgweb.cgi
All well and good, it serves perfectly there. My target is to subdomain it as:
http://hg.my.com/
with no trailing cgi-bin/hgweb.cgi
I have gotten the following URL to work with the config given below:
http://hg.my.com/cgi-bin/hgweb.cgi
... but it doesn't access the css and images properly (unlike above perfect service)
My config so far:
ScriptAlias /hg "/cgi-bin/hgweb.cgi"
<VirtualHost *:80>
ServerName hg.my.com
ServerAlias hg.my.com
#ScriptAlias / "/cgi-bin/hgweb.cgi"
# <Directory />
# Order Deny,Allow
# Allow from all
# </Directory>
# ProxyPass /stylesheets !
# ProxyPass /javascripts !
# ProxyPass /images !
ProxyPassMatch ^.*/static(/.*\.css)$ http://localhost:91/cgi-bin/hgweb.cgi/static/$1
ProxyPassMatch ^.*/static(/.*\.js)$ http://localhost:91/cgi-bin/hgweb.cgi/static/$1
ProxyPassMatch ^.*/static(/.*\.png)$ http://localhost:91/cgi-bin/hgweb.cgi/static/$1
ProxyPassMatch ^.*/static(/.*\.gif)$ http://localhost:91/cgi-bin/hgweb.cgi/static/$1
ProxyPreserveHost On
ProxyPass / http://localhost:91/cgi-bin/hgweb.cgi
ProxyPassReverse / http://localhost:91/cgi-bin/hgweb.cgi
<Proxy *>
#DirectoryIndex hgweb.cgi
#ScriptAlias / /hgweb.cgi
# # Order Allow,Deny
# # Allow from all
Order Deny,Allow
Allow from 127.0.0.1
AuthUserFile C:\wamp\.htpasswd
AuthName "Please Log In"
AuthType Basic
require user admin
require user dev
</Proxy>
</VirtualHost>
Obviously I am using the time honored google-trial-and-error approach and am out of my depth here.
Thus, my energetic egos mindless determinination for self-reliance, which otherwise seems to serve so well, now exhausted and filled with animosity toward the problem at hand -- brings me here, hat in hand, to ask:
"Brother, can you spare a dime?"

Why run apache on both 80 and 91? Is 91 just to serve up the static content? Unless I'm missing one of your requirements you shoudl be able to do whatever you need with something like this:
<VirtualHost *:80>
ServerName hg.my.com
ScriptAlias / "/cgi-bin/hgweb.cgi"
<Location />
Order Deny,Allow
AuthUserFile C:\wamp\.htpasswd
AuthName "Please Log In"
AuthType Basic
require user admin
require user dev
</Location>
</VirtualHost>
You shouldn't need a proxy, or separate rules for static (Mercurial will serve them up just fine).

Just put a slash after the script:
ScriptAlias /hg "/cgi-bin/hgweb.cgi/"

Related

Apache VirtualHost with authentication, websockets

I'm running a Spotify server on my Raspberry Pi at my school's robotics shop. It's on the school wifi network and it's accessed through a webpage http://localhost:6680. I wanted to add basic HTTP authentication (username/password) because people were being malicious, so I'm using an Apache VirtualHost as a proxy with basic authentication.
In addition, the webserver requires WebSockets to function through the same port. I successfully set up a VirtualHost file and it's working fine... except it's not working on Safari or iOS. After looking in the console, all WebSocket requests in Safari are returning a 401 error:
WebSocket connection to 'ws://XX.XXX.XX.XXX/iris/ws/' failed: Unexpected response code: 401
After looking into this more, apparently it's a known bug with Safari. Here's the VirtualHost file:
<VirtualHost *:80>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Proxy *>
Allow from all
</Proxy>
ProxyRequests On
ProxyPass /mopidy/ws/ ws://localhost:6680/mopidy/ws/
ProxyPassReverse /mopidy/ws/ ws://localhost:6680/mopidy/ws/
ProxyPass /iris/ws/ ws://localhost:6680/iris/ws/
ProxyPassReverse /iris/ws/ ws://localhost:6680/iris/ws/
<Location />
ProxyPass http://localhost:6680/
ProxyPassReverse http://localhost:6680/
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Location>
</VirtualHost>
Is there any way we can simply remove authentication for just the websockets but not for the webpage? Considering how this is structured, that should be the case, but it isn't. Thanks!
I don't know much about WebSockets, but I do know that you should always declare the VirtualHost port you are listening to if you want to separate traffic.
Try to do so by adding two different VirtualHost in the same configuration:
<VirtualHost *:80>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/">
AllowOverride All
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
</VirtualHost>
From now on I can't help further:
<VirtualHost *:6680>
somethingsomethingsomething
</VirtualHost>
Update
Traffic different from :80 is blocked in your school, I guess.
I can suggest a more radical approach which is banning all traffic from Safari (both desktop and mobile).
You can modify the config by adding a redirect to a courtesy page like "your browser is not supported".
<Location *>
SetEnvIfNoCase User-Agent .*Safari* bad_browser
Deny from env=bad_browser
</Location>
Make sure you are proxying over your websockets if needed. They might look something like this:
ProxyPass /socket.io http://localhost:6680/socket.io
ProxyPassReverse /socket.io http://localhost:6680/socket.io
Try do next, like described here:
#In your case it will be like this:
<LocationMatch /(iris|mopidy)/ws>
Allow from all
</LocationMatch>
Update: Please be aware this rule to wide as you see.

Trac & Apache Server: SSL & Virtual Hosts not working

I have configured an Ubuntu 16.04 Server with Apache and installed Trac 1.2.2 on it. I would like to access the Trac installation using SSL via https://subdomain.example.com
I have the following two .conf-files in /etc/apache2/sites-available/ right now:
ssl.conf:
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache.crt
SSLCertificateKeyFile /etc/ssl/private/apache.key
DocumentRoot /var/www/html/
testinstallation.conf:
WSGIScriptAlias /trac/testinstallation /var/www/html/trac/testinstallation/cgi-bin/trac.wsgi
<Location /trac/testinstallation>
AuthType Digest
AuthName "testinstallation"
AuthUserFile /var/lib/trac/testinstallation/.htdigest
Require valid-user
</Location>
When I open https://subdomain.example.com/trac/testinstallation, everything works as it should - but I would like to access my Trac-environment via https://subdomain.example.com. When I change the DocumentRoot in ssl.conf to /var/www/html/trac/testinstallation, I only get to see two folders, but not the Trac-environment (I don't know how to implement the WSGIScriptAlias to the ssl.conf). Can anybody help me with this problem?
Another question: Can I run multiple installations of Trac on one server using SSL? If yes, I would probably need another VirtualHost-file - but what should be in there?
The first parameter of WSGIScriptAlias is the URL-path. So to access your Trac installation over just the subdomain, you can modify the WSGIScriptAlias directive to
WSGIScriptAlias / /var/www/html/trac/testinstallation/cgi-bin/trac.wsgi
There is no need of mentioning the DocumentRoot. The WSGIScriptAlias directive takes care of it. If you want to run multiple Trac installations over multiple subdomains, repeat the same process that you have followed. i.e.,
Deploy project directory
Create Trac users
Create vhost and enable site
Else you can run multiple Trac installation as multiple subdirectories under the same subdomain by defining multiple WSGIScriptAlias directives in the same vhost file.
Example of vhost file for multiple Trac installations (test1 and test2) over single subdomain:
trac.conf
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/ssl/certs/apache.crt
SSLCertificateKeyFile /etc/ssl/private/apache.key
</VirtualHost>
WSGIScriptAlias /test1 /var/www/html/trac/test1/cgi-bin/trac.wsgi
<Location /login>
AuthType Digest
AuthName "test1"
AuthUserFile /var/lib/trac/test1/.htdigest
Require valid-user
</Location>
WSGIScriptAlias /test2 /var/www/html/trac/test2/cgi-bin/trac.wsgi
<Location /login>
AuthType Digest
AuthName "test2"
AuthUserFile /var/lib/trac/test2/.htdigest
Require valid-user
</Location>

Apache: Using reverse proxy and run local website

On my linux machine I have apache2 running as a reverse proxy, because I wanted to make another webserver on port 8083 accessible while also making it password protected. For this I added this to my apache2.conf:
<VirtualHost *:80>
<Location / >
AuthName "Protected Area"
AuthType Basic
AuthUserFile /home/pi/.htpasswd
Require valid-user
</Location>
ProxyPass / http://localhost:8083/
ProxyPassReverse / http://localhost:8083/
</VirtualHost>
That works like a charm, but now I also want to use apache to serve a site, I would like to do this by making something like /mysite point to /var/www, but I can't really figure out how to do this or if it is even possible.
Any ideas?
I think you have two options:
1. Put the proxy in a separate <Location /someurl> and put the site outside. Requests to http://localhost/someurl/ will be proxied, everything else is the local site:
<VirtualHost *:80>
<Location /someurl >
# Password protection omitted for brevity
ProxyPass http://localhost:8083/
ProxyPassReverse http://localhost:8083/
</Location>
# Here is the site
DocumentRoot /var/www
# ... etc site config
</VirtualHost>
2. Use two separate VirtualHosts, one for the proxy and one for the site. You will need two separate hostnames pointing to your local ip. For local operations only, use /etc/hosts. In this exemple http://a.localhost/ is the proxy, http://b.localhost is the site:
/etc/hosts:
127.0.0.1 a.localhost
127.0.0.1 b.localhost
Apache config:
# This is the proxy, http://a.localhost/
<VirtualHost *:80>
ServerName a.localhost
# Do password protection as needed
ProxyPass / http://localhost:8083/
ProxyPassReverse / http://localhost:8083/
</VirtualHost>
# This is the site, http://b.localhost/
<VirtualHost *:80>
ServerName b.localhost
DocumentRoot /var/www
# ... etc site config
</VirtualHost>
I would probably go for two separate VirtualHosts, keeping stuff nicely separated.

How can I internally point to a domain but keep the url with the subdomain constant?

I have a domain www.example.com hosted in one location.
I have created another account with a different hosting provider that allows me to create subdomains: www.test1.example.com and www.test2.example.com
I am putting a custom page for each of the subdomains when the user goes to test1.example.com, test2.example.com....
After the user logs in on this custom page, I want to maintain the subdomain (of test1.example.com) but internally have all requests point to www.example.com.
I am running the custom pages on Apache and the domain pages on Apache Tomcat - I think that using 'mod_rewrite' is the way to go?
Put the following in a .htaccess file in your subdomain's document root:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^test1\.example\.com$
RewriteRule ^/(.*) http://example.com/$1 [redirect,last]
To enable mod_rewrite on a modern Ubuntu web server run this command:
sudo ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
Make sure AllowOverride is set to "All" in your VirtualHost configuration (for example /etc/apache2/sites-available/default):
<Directory /var/www/document/root/>
AllowOverride All
</Directory>
then restart Apache:
sudo /etc/init.d/apache2 restart
So, basically the answer I found that worked was to use mod_proxy. I enabled that as an Apache module and included the following in my httpd-vhosts.conf file.
NameVirtualHost *:80
<VirtualHost *:80>
ServerName test1.example.com
DocumentRoot "location_of_the_custom_page"
ErrorLog "logs\errors.log"
<directory "D:\wamp\www\capitalfloat">
Options Indexes FollowSymLinks
AllowOverride all
Order Deny,Allow
Deny from all
Allow from all
</directory>
</VirtualHost>
<VirtualHost *:80>
ServerName localhost2
ServerAlias *.example.com
ErrorLog "logs\errors.log"
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://www.example.com
ProxyPassReverse / http://www.example.com
</VirtualHost>
I also had to include 'http://www.example.com' and 'test1.example.com' in the Windows Host File (For me, C:\Windows\System32\drivers\etc\hosts). In my custom login page, the request goes to 'example.com' and all subsequent requests are sent to 'www.example.com' but the url still shows 'test1.example.com/...'

How to block URL pattern using Apache with mod_wsgi

I have a web2py application run under Apache via mod_wsgi. How do I restrict access to the admin page (www.myapp.com/admin) based on source IP?
Ideally, I do it directly within Apache for two reasons: 1) I assume that Apache has more effective access to the source IP [citation needed] and 2) I don't feel like modifying the stock admin page in web2py to block specific IPs.
My (abridged) configuration looks something like this:
<VirtualHost *:80>
WSGIDaemonProcess web2py user=myapp group=myapp
WSGIProcessGroup web2py
WSGIScriptAlias / /home/myapp/myapp/wsgihandler.py
TimeOut 45
ServerName myapp.com
ServerAlias www.myapp.com
<Directory /home/myapp/myapp>
AllowOverride None
Order Allow,Deny
Deny from all
<Files wsgihandler.py>
Allow from all
</Files>
</Directory>
#======================================
# THIS IS WHAT I TRIED THAT DIDN'T WORK
<Directory /home/myapp/myapp/admin>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Directory>
#======================================
AliasMatch ^/static/(.*) \
/home/myapp/myapp/applications/myapp/static/$1
<Directory /home/myapp/myapp/applications/myapp/static/>
Options -Indexes
Order Allow,Deny
Allow from all
</Directory>
# HTTPS enforcement
# Out of convenience, forward /a* to https, covers /admin /appadmin and /a (front facing admin)
RedirectMatch ^/a(.*) https://myapp.com/a$1
RedirectMatch ^/c/(.*) https://myapp.com/c/$1
RedirectMatch ^/w/user/login(?:/(.*)|$) https://myapp.com/w/user/login/$1
RedirectMatch ^/w/user/register(?:/(.*)|$) https://myapp.com/w/user/register/$1
CustomLog /var/log/apache2/access.log common
ErrorLog /var/log/apache2/error.log
</VirtualHost>
Note that I have a similar VirtualHost for port 443. I just didn't include it for the sake of redundancy.
Normally, it is my understanding that I could use something like the directory notation to deny access to certain directories. However, the above didn't work and I wonder if it has to do with the WSGIScriptAlias directive.
Use:
<Location /admin>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Location>