# nginx + phpMyAdmin + SSL aliasing problems



## nanotek (Jan 8, 2014)

My situation:


I can configure nginx so that the server listens on both 80 and 443 but /phpmyadmin -- nested as a location in the main (only) server block -- cannot be accessed securely (https://), only unencrypted (http://): 500 error. The literature indicates this is the correct configuration and should be working.

I can configure nginx so that the server listens on 80 and /phpmyadmin -- in its own server block listening on 443 -- can be accessed securely but the server root cannot: 404 error. Obviously because only the /phpmyadmin server is instructed to listen on 443, i.e. not the right configuration.

I can't configure nginx so that the server listens on both 80 and 443 and returns /phpmyadmin -- nested as a location in the main server block -- requests on both 80 and 443. Please provide example configurations to make this work.

Basically, I want the server to serve HTTP and HTTPS requests of the same content, and I just want an alias for server.com/phpmyadmin to serve the default FreeBSD port install directory of /usr/local/www/phpMyAdmin. This is simple with Apache[1], but not so simple with nginx.

According to the nginx documentation, this should be achieved with either the root[2] or alias[3] directive, nested within a location[4] context residing in the main server[5] block. With that in mind, here is my configuration (scroll to the end of nginx.conf file to see the phpMyAdmin configuration and to the third code excerpt to see the php-fpm configuration) which exemplifies scenario 1 described above:


```
user www www;
worker_processes  1;
    error_log  /var/log/nginx-error.log;
    pid           /var/run/nginx.pid;

events {
    worker_connections  1024;
    use kqueue;
}

http {
    include  /usr/local/etc/nginx/conf.d/options;
    include  /usr/local/etc/nginx/mime.types;
    access_log   /var/log/nginx-access.log;
    log_format  main  '$remote_addr $host $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_cipher $request_time';
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
      
server {
    add_header  Cache-Control "public";
    add_header  X-Frame-Options "DENY";
    access_log  /var/log/nginx/access.log main buffer=32k;
    error_log   /var/log/nginx/error.log error;
    expires     max;
    limit_req   zone=gulag burst=200 nodelay;
    listen   80;
    listen 443 ssl;
    ssl_certificate /path/to/crtchn.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_dhparam /path/to/dh4096.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"
    ssl_prefer_server_ciphers on;
    server_name  localhost;
    
location ~* / {
        root   /usr/local/www/nginx;
        index  index.htm index.html index.php;
        include   /usr/local/etc/nginx/conf.d/php-fpm;
}

location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
      access_log        off;
      expires           30d;
      root /usr/local/www/nginx;
}

location = /favicon.ico {
     return 204;
}

error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 495 496 497
               500 501 502 503 504 505 506 507 /error_page.html;

location  /error_page.html { internal; }

location ~ /\.ht {
        deny  all;
}

location /phpmyadmin {
          alias       /usr/local/www/phpMyAdmin/;
          index index.php index.html;
}

location ~ ^/phpmyadmin/(.*\.php)$ {
          root                /usr/local/www/phpMyAdmin/;
          fastcgi_pass        unix:/var/run/php-fpm.sock;
          include             fastcgi_params;
          fastcgi_param       SCRIPT_FILENAME /usr/local/www/phpMyAdmin/$1;
          fastcgi_param       DOCUMENT_ROOT /usr/local/www/phpMyAdmin;
    }
  }
}
```

nginx/conf.d/options:

```
http {
    client_body_timeout  5s;
    client_header_timeout  5s;
    keepalive_timeout  75s;
    send_timeout  15s;
    charset  utf-8;
    default_type  application/octet-stream;
    gzip  off;
    gzip_static  on;
    gzip_proxied  any;
    ignore_invalid_headers  on;
    keepalive_requests  50;
    keepalive_disable  none;
    max_ranges  1;
    msie_padding  off;
    open_file_cache  max=1000 inactive=2h;
    open_file_cache_errors  on;
    open_file_cache_min_uses  1;
    open_file_cache_valid  1h;
    output_buffers  1 512;
    postpone_output  1440;
    read_ahead  512K;
    recursive_error_pages  on;
    reset_timedout_connection  on;
    sendfile  on;
    server_tokens  off;
    server_name_in_redirect  off;
    source_charset  utf-8;
    tcp_nodelay  on;
    tcp_nopush  off;
    gzip_disable  "MSIE [1-6]\.(?!.*SV1)";
    limit_req_zone  $binary_remote_addr  zone=gulag:1m   rate=60r/m;
}
```

nginx/conf.d/php-fpm:

```
location ~ \.php$ {
        try_files      $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /usr/local/www/nginx$fastcgi_script_name;
        fastcgi_intercept_errors        on;
        fastcgi_ignore_client_abort     off;
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
        fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;
        include fastcgi_params;
}
```

This _should_ be working but it isn't. Can someone here who does have nginx running as a webserver serving the same content over HTTP and HTTPS and has phpMyAdmin working over both HTTP and HTTPS please provide their relevant configuration?

Ultimately, I would like a concise nginx.conf with alias configuration in separate files in the conf.d directory, similar to http and server configuration contained in separate files in conf.d, but I can't even get aliasing working as it is!

*[1]* Apache httpd.conf which takes care of the http server and instructs Apache to include the https configuration contained in the /extra directory:

```
ServerRoot "/usr/local"
Listen 80
LoadModule ssl_module libexec/apache24/mod_ssl.so
LoadModule socache_shmcb_module libexec/apache24/mod_socache_shmcb.so
ServerName server.com
<Directory />
    Options FollowSymLinks
    AllowOverride All
    Require all denied
</Directory>
DocumentRoot "/usr/local/www/apache24/data"
<Directory "/usr/local/www/apache24/data">
  Options Indexes FollowSymLinks
  Options FollowSymLinks
    AllowOverride Al
</Directory>
Include etc/apache24/extra/httpd-vhosts.conf
Include etc/apache24/extra/httpd-ssl.conf
Include etc/apache24/Includes/*.conf
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
```

Apache extra/httpd-ssl.conf, which provides configuration for https server:

```
Listen 443
<VirtualHost _default_:443>
  DocumentRoot "/usr/local/www/apache24/data"
  ServerName server.com:443
  SSLEngine on
  SSLCertificateFile crt.pem
  SSLCertificateKeyFile key.pem
  SSLCertificateChainFile ca.chn
</VirtualHost>
```

phpMyAdmin alias in httpd.conf which enables both http and https requests to server.com/phpmyadmin (I need the nginx equivalent of this!):

```
Alias /phpmyadmin "/usr/local/www/phpMyAdmin"
<Directory "/usr/local/www/phpMyAdmin">
  Options None
        AllowOverride None
        Require all granted
</Directory>
```

And that's it. The ONE alias created in httpd.conf will be served whether the client requests http:// or https://server.com/phpmyadmin.

*[2]* http://nginx.org/en/docs/http/ngx_http_ ... .html#root
*[3]* http://nginx.org/en/docs/http/ngx_http_ ... html#alias
*[4]* http://nginx.org/en/docs/http/ngx_http_ ... l#location
*[5]* http://nginx.org/en/docs/http/ngx_http_ ... tml#server


----------



## eetlotsgloo (Jan 14, 2014)

That looks right to me as well, though I honestly haven't digested the whole thing. I stopped using phpMyAdmin because it was such a pig, but could it have something to do with this? I don't remember if PMA checks $_SERVER[“HTTPS”] or not.

I've converted one guy to Adminer and he loves it. I like it because I don't have to deal with stuff like this :h


----------



## nanotek (Jan 14, 2014)

Thanks, @eetslotsgloo. I ended up figuring it out [1], but NGINX *really* sucks when you're already used to Apache! Basically, location requests aren't explicitly subject to their own directives (in a sense). You might have directives used from a generic .php$ location block for specific URI (e.g. domain.tld/phpmyadmin) requests if you haven't structured your configuration in accordance with NGINX's prefix and regular expression indexing order. And try find a) what regex NGINX uses and b) what they actually do! I think I'll give lighttpd a try. Thanks for the Adminer suggestion, I'm going to look at that too.

[1] see this for full configuration

```
location ^~ /phpmyadmin {
        access_log  off;
        rewrite ^  /phpMyAdmin/ permanent;
}
 
location /phpMyAdmin {
        root /usr/local/www;
        index index.php index.html;
 
                location ~ ^/phpMyAdmin/(.*\.php)$ {
                        root /usr/local/www/;
                        include conf.d/php-fpm;
                }
}
```


----------

