GithubHelp home page GithubHelp logo

Apache configuration on macOS about mkcert HOT 17 CLOSED

fooness avatar fooness commented on August 15, 2024
Apache configuration on macOS

from mkcert.

Comments (17)

loilo avatar loilo commented on August 15, 2024 3

EDIT: For follow-up readers from search or other sources: I updated the description below to use .dev.localhost instead of .localhost since that didn't work.

I got my Apache VHosts to work successfully with mkcert.

The example below corresponds to my setup of mapping [anything].dev.localhost to /Users/[username]/Sites/[anything], where [username] is the user I'm running on my machine.

It works with the help of dnsmasq.


My pre-existing VHost configuration:

<VirtualHost *:80>
  ServerName localhost
  ServerAlias *.dev.localhost
 
  CustomLog "/Users/[username]/Sites/.logs/localhost_access_log" combinedmassvhost
  ErrorLog "/Users/[username]/Sites/.logs/localhost_error_log"
 
  VirtualDocumentRoot /Users/[username]/Sites/%-2+
</VirtualHost>

I created a .crt folder in /Users/[username]/Sites and executed the following command in there:

mkcert '*.dev.localhost'

Subsequently, I added the following configuration block to my Apache config. As you can see, if you compare it to the HTTP block above, it's pretty straightforward:

<VirtualHost *:443>
  ServerName localhost
  ServerAlias *.dev.localhost

  SSLCertificateFile "/Users/[username]/Sites/.crt/_wildcard.dev.localhost.pem"
  SSLCertificateKeyFile "/Users/[username]/Sites/.crt/_wildcard.dev.localhost-key.pem"
 
  CustomLog "/Users/[username]/Sites/.logs/localhost_access_log" combinedmassvhost
  ErrorLog "/Users/[username]/Sites/.logs/localhost_error_log"
 
  VirtualDocumentRoot /Users/[username]/Sites/%-2+
</VirtualHost>

Hope this helps.

from mkcert.

brimarq avatar brimarq commented on August 15, 2024 2

FWIW, I have a macOS setup similar to @loilo with Homebrew httpd + dnsmasq using "automatic" virtual-hosts configuration. Instead of using a wildcard cert with a subdomain, I use a shell function in my .bash_profile that uses the directory names from my ~/Sites directory to create a SAN list for running mkcert. This way, I can continue to use [project_dir].test instead of [project_dir].[subdomain].test. Of course, I have to run the function again if I create a new project in ~/Sites; but, like @loilo and @fooness , I prefer not having to use a subdomain unless I actually want one. This could always be expanded to create a new project dir in ~/Sites and then make new certs... lots of possibilities there.

function mklocalcerts() {

  local sites_dir=$HOME/Sites
  local certs_dir=$(brew --prefix)/etc/httpd/crt
  local tld='test'
  # Add persistent SANs here (localhost, loopback and/or fixed LAN IP addresses)
  local subj_alt_names=( 'localhost' '127.0.0.1' '::1'  )

  # Add dir names in $sites_dir to $subj_alt_names array, appending the $tld to each
  for f in $sites_dir/*; do 
    [[ -d $f ]] && subj_alt_names+=("${f##*/}.$tld");
  done

  # if $certs_dir doesn't exist, create it
  [[ ! -e $certs_dir ]] && mkdir -pv -m 755 $certs_dir;
  
  # Create cert and key files in $certs_dir 
  mkcert -cert-file $certs_dir/server.pem -key-file $certs_dir/server-key.pem ${subj_alt_names[@]};
  
  return 0;
}

@FiloSottile, thanks for this handy tool!

from mkcert.

loilo avatar loilo commented on August 15, 2024 1

Sooo... here's what I didn't realize:

I have in fact created a *.localhost certificate on my machine (as explained above), but it doesn't actually work. I dind't notice that because it was just one certificate among others, and the others worked.

Now the difference is, that the others are not top level wildcard certificates but actually use subdomains of localhost (such as *.web.localhost, *.public.localhost etc.)

Wildcard certificates work for those, but not for *.localhost because browsers don't support top level wildcard certificates for security reasons (mkcert even warns you if you try to create such a certificate, shouldn't have ignored that).

So, two ways to work around it:

  • Route all your local development stuff through a subdomain, e.g. [anything].dev.localhost. It's not pretty, but it allows you to omit any manual labor for certificates or server configuration.
  • Create certificates and HTTPS server configurations by hand. This gives you the pretty URLs described above ([anything].localhost), but you'll have to create a certificate and Apache configuration block whenever you want to use a new subdomain.

Sorry for misleading you previously.

If you need help with adjusting the configurations to one of the mentioned approaches, feel free to hit me up here. :)

from mkcert.

fooness avatar fooness commented on August 15, 2024 1

Finally got it working with the suffix .dev.localhost … thank you so much.

I also read the warning in regards of wildcard certificates, it said some browsers might have problems if I remember correctly. Maybe it’s more than just some

Really happy it’s properly working now!

from mkcert.

nickkaczmarek avatar nickkaczmarek commented on August 15, 2024

I'm using it on macos, but only for local development with webpack dev server, but with that you effectively just run mkcert -install which I believe creates a local trusted Certificate Authority and then in the project, and maybe this part isn't strictly necessary to run in the project, but I run mkcert hostname and then point webpack dev server to that. In this case I ran mkcert localhost because webpack starts the server at localhost:3001. I could be wrong about my explanations, but this process is working for me so far. I'm sure @FiloSottile would have more insight into the inner workings.

export const devServer = {
  contentBase: path.join(__dirname, 'static'),
  port: 3001,
  https: {
    key: fs.readFileSync('./localhost-key.pem'),
    cert: fs.readFileSync('./localhost.pem'),
  },
  open: true,
  proxy: {
    '/api': {
      target: 'http://localhost:8080',
      secure: false,
    },
  },

from mkcert.

fooness avatar fooness commented on August 15, 2024

Thank you very much, @loilo … that’s exactly what I’m looking for. I added your lines (excluding the combined custom and error log) to my /etc/apache2/extra/httpd-vhosts.conf … I suppose I still need to specify a <Directory "…"> block like the following, is this correct?

<Directory "/Users/[username]/Sites">
    Options Indexes MultiViews SymLinksIfOwnerMatch
    MultiviewsMatch Any
    AllowOverride All
    Require local
</Directory>

<VirtualHost *:80>
    VirtualDocumentRoot /Users/[username]/Sites/%1
    ServerName localhost
    ServerAlias *.dev
</VirtualHost>

<VirtualHost *:443>
    VirtualDocumentRoot /Users/[username]/Sites/%1
    ServerName localhost
    ServerAlias *.dev
    SSLEngine on
    SSLCertificateFile "/Users/[username]/Sites/_certs/_wildcard.dev.pem"
    SSLCertificateKeyFile "/Users/[username]/Sites/_certs/_wildcard.dev-key.pem"
</VirtualHost>

I think it might be working now, though unfortunately I still get invalid/insecure certificate errors in Chromium and Firefox. Any ideas on what’s the problem? Or do both browser not support wildcard certificates?

How was dnsmasq configured? For an older setup with another approach, I’m having a file called /etc/resolver/dev with an entry of nameserver 127.0.0.1dev/*.dev, in my case, corresponds to your ServerAlias of *.localhost

Does anything need to be defined in /etc/apache2/extra/httpd-ssl.conf? Do you use SSLEngine on and server wide SSLCertificateFile/SSLCertificateKeyFile somewhere?

What exactly does %-2+ stand for?

from mkcert.

loilo avatar loilo commented on August 15, 2024

So, in order:

Yes, you still need the <Directory> directive.

Mine looks like this:

<Directory "/Users/[username]/Sites">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    <IfModule mod_authz_core.c>
        Require all granted
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Allow from all
    </IfModule>
</Directory>

My setup works just fine in Chrome and Firefox, so it's probably not the browsers.


dnsmasq

I'm assuming you installed dnsmasq via Homebrew.

  1. At the end of $(brew --prefix)/etc/dnsmasq.conf, add the line
    address=/localhost/127.0.0.1
  2. Create the file /etc/resolver/localhost, and add to it the following line:
    nameserver 127.0.0.1
    
  3. (Restart the dnsmasq service: brew services restart dnsmasq)

SSL

I'm not really sure what exactly is required to be configured. I'm by no means an Apache expert and it's been a while ago that I set up my local webserver.

I'm having the ssl_module enabled in my httpd.conf:

LoadModule ssl_module lib/httpd/modules/mod_ssl.so

Regarding your question, I definitely have an httpd-ssl.conf included in the main httpd.conf which contains a Listen 443. There's some other stuff I don't think is relevant to your case. It's also the default content that pre-existed in that file, I haven't touched it at all.


%-2+

This is a token which Apache replaces with the 2nd level domain. If you're on foo.localhost, that's going to be foo. If you had a setup with deeper nested domains, like foo.bar.localhost, %-2+ will be bar while %-3+ will be foo.


I assume you have already restarted your Apache after adjusting your config?

from mkcert.

fooness avatar fooness commented on August 15, 2024

In regards of dnsmasq.conf, the only difference is I’m having a . in front of my top level domain, like address=/.dev/127.0.0.1 in my case, which in your case would correspond to address=/.localhost/127.0.0.1

Everything else in my setup pretty much matches yours.

Virtualhosts syntax/config check:

$ sudo apachectl -S
VirtualHost configuration:
*:80                   localhost (/private/etc/apache2/extra/httpd-vhosts.conf:31)
*:443                  localhost (/private/etc/apache2/extra/httpd-vhosts.conf:39)
ServerRoot: "/usr"
Main DocumentRoot: "/Users/[username]/Sites"
Main ErrorLog: "/private/var/log/apache2/error_log"
Mutex mpm-accept: using_defaults
Mutex ssl-stapling-refresh: using_defaults
Mutex rewrite-map: using_defaults
Mutex ssl-stapling: using_defaults
Mutex ssl-cache: using_defaults
Mutex default: dir="/private/var/run/" mechanism=default
PidFile: "/private/var/run/httpd.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="_www" id=70
Group: name="_www" id=70

And I restarted Apache several times via sudo apachectl -k restart, yes. Unfortunately without success. Really can’t figure out the problem here, unfortunately. Thank you very much for your efforts!

from mkcert.

loilo avatar loilo commented on August 15, 2024

You're welcome. Sorry it didn't work out. 😕

from mkcert.

fooness avatar fooness commented on August 15, 2024

Maybe someone else sees a problem we just didn’t recognize.

from mkcert.

loilo avatar loilo commented on August 15, 2024

For the record, I'm not using macOS' built-in Apache but a version installed from Homebrew. I don't think that it matters, but for finding problems every tiny bit could be relevant.

from mkcert.

fooness avatar fooness commented on August 15, 2024

Maybe it’s just the mkcert certificates that are wrong …

I was just testing everything in Safari, which I normally don’t use, and there I got a message like:

[username]@[hostname].local
Issued by: mkcert [username]@[hostname].local
Expires: Wednesday, 30. August 2028 at 09 h 25 min 48 s
Central European Summer Time
“[username]@[hostname].local” certificate name does not match input

“input”, being it the URL, is [foldername].dev (or .localhost in your case).

from mkcert.

loilo avatar loilo commented on August 15, 2024

Also .dev is a registered TLD, I don't know how that interferes with stuff.

from mkcert.

fooness avatar fooness commented on August 15, 2024

I see … /etc/resolver/dev should take care of this, though … I changed everything to .localhost and it’s still the same as before.

from mkcert.

loilo avatar loilo commented on August 15, 2024

It should, in fact. However, at least Chrome did things with that TLD anyways (forcing all .dev on a HTTPS redirect for example) which is why at some point I switched to .localhost.

Again, I don't think that should be an issue, but it's worth mentioning.

from mkcert.

loilo avatar loilo commented on August 15, 2024

Nice, glad to hear that. If this is no longer an issue for you, I guess you could close this one. 🙂

from mkcert.

AndreKelling avatar AndreKelling commented on August 15, 2024

#56 (comment)
got it too...

so need to create like this mkcert '*.dev.localhost' and not mkcert '*.localhost'

from mkcert.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.