How to Redirect non www to www with https

I'm using Apache2 on ubuntu 20*. directing domain to www from port :80 on http works with the code:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias *.example.com
    Redirect 301 / https://www.example.com/
</VirtualHost>

now the only part remaining is redirecting the https version to the same. When I write the code below, all urls including the one I'm redirecting to gets redirected with error REDIRECTED_TOO_MANY_TIMES:

<VirtualHost *:443>
  ServerName example.com

  Redirect 301 / https://www.example.com/
</VirtualHost >

so where is this error coming from and how should I fix it?

summary: Redirect https://domain to https://www.domain

12 Replies

Try this:

<VirtualHost *:80>
    ServerName example.com
    Redirect 301 / https://www.example.com/
</VirtualHost>

and

<VirtualHost *:443>
  ServerName www.example.com
</VirtualHost >

-- sw

changing the config to that leads to a different error on https://example.com:

HTTP/1.1 400 Bad Request
Date: Tue, 28 Jun 2022 11:17:24 GMT
Server: Apache/2.4.48 (Ubuntu)
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Connection: close
Content-Type: text/html

The HTTP 400 Bad Request response indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).

According to the configuration I gave you, there is no https://example.com …only:

You could try this:

<VirtualHost *:443>
  ServerName www.example.com
  ServerAlias example.com
</VirtualHost >

Frankly, what I would do is handle the whole equivalency of example.com and www.example.com with DNS…it's where the solution to that belongs. Then, you only have to configure http & https cases.

  • Create two A/AAAA records for example.com…one for IPv4 and one for IPv6. I use the default TTL (86400).

  • Create two A/AAAA records for www…one for IPv4 and one for IPv6. I use the default TTL (86400).

Note the second A/AAAA record is for wwwNOT www.example.com . IPv6 can come later…if you use it (which I do).

Wait 24-48 hrs for your changes to propagate. After that, you've cut your apache configuration by half.

Failing all that, get each <VirtualHost> working separately, then mess with the redirect(s). That way you have something to fall back to when the redirects (inevitably) don't work right.

-- sw

I have done as you suggested adding DNS records but https://example.com still doesn't work while http://example.com works.

It fails with error:

Bad Request (400)

The only thing I can think of is that your certificate and/or SSL configuration are incorrect. You omitted the details of that from your https <VirtualHost> (the one for port 443).

As I explained above, a 400 response indicates the client has made a bad request. That would certainly be the case if SSL is not set up correctly.

— sw

I have done all this even issued SSL for both domains but it's still not working.

Post your a sanitized <VirtualHost *:443> configuration (including all the SSL directives)…the whole configuration for your virtual host.

-- sw

P.S. Just getting a cert is not going to help you. You have to tell apache to use it. That's the stuff I'm looking for. Also, post it between two sets of ``` (3 backticks…the key next to the 1 on your keyboard) so that this comment board will format it correctly (and I can read it).

hi sorry for the delay. Here's my virtual host port 80 config:

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.

        ServerName pokomodictionary.com
        ServerAlias www.pokomodictionary.com

        Redirect 301 / https://www.pokomodictionary.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf


RewriteEngine on
RewriteCond %{SERVER_NAME} =www.pokomodictionary.com [OR]
RewriteCond %{SERVER_NAME} =pokomodictionary.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Here's my SSL config on port 443:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.

        ServerName pokomodictionary.com
        ServerAlias www.pokomodictionary.com

        #Redirect 301 / https://www.pokomodictionary.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

         Alias /static /home/dvlpr69/pokomowiki/staticfiles
        <Directory /home/dvlpr69/pokomowiki/staticfiles>
                Require all granted
        </Directory>

        <Directory /home/dvlpr69/pokomowiki/pokowiki>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        WSGIScriptAlias / /home/dvlpr69/pokomowiki/pokowiki/wsgi.py process-group=pokomowiki.co.ke
      WSGIDaemonProcess pokomowiki.co.ke python-home=/home/dvlpr69/pokomowiki/venv python-path=/home/dvlpr69/pokomowiki
      WSGIProcessGroup pokomowiki.co.ke

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} =www.pokomodictionary.com [OR]
# RewriteCond %{SERVER_NAME} =pokomodictionary.com
# RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/www.pokomodictionary.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.pokomodictionary.com/privkey.pem
</VirtualHost>
</IfModule>

Thanks in advance…

Sorry for the late response… I was driving home from Seattle most of yesterday…

Leaving out your comments, I'd structure the VirtualHost like this (I'm assuming that mod_ssl is enabled…if it's not, this VirtualHost definition is going to be null):

<IfModule mod_ssl.c>
<VirtualHost *:443>

        ServerName pokomodictionary.com
        ServerAlias www.pokomodictionary.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        Include /etc/letsencrypt/options-ssl-apache.conf

        SSLCertificateFile /etc/letsencrypt/live/www.pokomodictionary.com/cert.pem  # CHANGE HERE
        SSLCertificateKeyFile /etc/letsencrypt/live/www.pokomodictionary.com/privkey.pem
        SSLCACertificateFile /etc/letsencrypt/live/www.pokomodictionary.com/chain.pem  # CHANGE HERE

        Alias "/static" "/home/dvlpr69/pokomowiki/staticfiles"
        <Directory /home/dvlpr69/pokomowiki/staticfiles>
                SSLOptions +StdEnvVars  # ADDED THIS (adds appropriate CGI env vars for SSL)
                AllowOverride None      # ADDED THIS (prevents honoring of .htaccess)
                Options -Indexes        # ADDED THIS (prevents directory lists)
                Require all granted
        </Directory>

        # LEAVE THIS PART OUT UNTIL YOU GET THE REST OF IT WORKING
        #
        #<Directory /home/dvlpr69/pokomowiki/pokowiki>
        #        <Files wsgi.py>
        #                Require all granted
        #        </Files>
        #</Directory>
        #
        #WSGIScriptAlias / /home/dvlpr69/pokomowiki/pokowiki/wsgi.py process-group=pokomowiki.co.ke
        #WSGIDaemonProcess pokomowiki.co.ke python-home=/home/dvlpr69/pokomowiki/venv python-path=/home/dvlpr69/pokomowiki
        #WSGIProcessGroup pokomowiki.co.ke

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

# RewriteEngine on  # YOU DON'T NEED THIS SINCE ALL YOUR REWRITE RULES
                    # ARE COMMENTED OUT

</VirtualHost>
</IfModule>

Basically, I did the following:

  • Moved the SSL config from the bottom to the top.
  • Removed use of fullchain.pem as the cert file and replaced it with the cert file and the CA cert file (I've never gotten fullchain.pem to work correctly!).
  • Added double quotes in Alias (prob not necessary but I had them in a working configuration for a site I have).
  • Added some options to the Directory (explained inline).
  • Turned off all the WSGI stuff (once you get the basic set up working, you can add that back in slowly…testing along the way; if you don't need this stuff, just leave it commented out or remove it).
  • Commented out enablement of mod_rewrite (all of your rewrite directives were commented out).

Frankly I think the problem was with your SSL config. The rest is just stylistic sugar to get you on the road. I hope this helps…

You should consult the logs when an error occurs. They can provide you with invaluable info about why.

-- sw

All the changes work but they seem to break when I uncomment the WSGI lines. It goes back to square one with the Bad request error

All the changes work but they seem to break when I uncomment the WSGI lines. It goes back to square one with the Bad request error

Well, you have your answer… The first question I would ask myself though is Do I really need this? If the answer is no, remove it all or leave it commented out.

If you do need it, do you have a file with the path /home/dvlpr69/pokomowiki/pokowiki/wsgi.py? Your Directory and Files directives suggest that you do. Does it have the right ownership? Does it have the right permissions? Get this stuff to work next…

As for the WSGI* directives, you're on your own. I don't know anything about that (or python). I do know enough to know that you need mod_wsgi enabled in your server for these to work though. Is that the case for you? mod_wsgi is not part of the standard apache 2.4.x distribution. You have to install it separately. It should be available as a package called libapache2-mod-wsgi-py3. See:

https://pypi.org/project/mod-wsgi/

for more info.

DANGER WILL ROBINSON! DANGER! DANGER!

If you don't have python3 installed (or the "right" version of python3), installing this package is going to drag in multiple giga-/mega-bytes of python3 and support files. If you do use python3, don't be surprised if you get another version just to make mod_wsgi run (and can possibly fail trying to run your WSGI python3 scripts). This is another reason for asking yourself Do I really need this?

-- sw

Thanks for all the help, I'll follow your suggestions and keep troubleshooting till it works.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct