Http in seafile client when ssl is forced

I made a small test just to see how secure the server is. I have port 80 open for letsencrypt, which i believe is the normal way of doing this.

As a test i changed https to http in the server connection address in the seafile client, and did a netstat -taucp | grep PID. I can see http requests to the server. I thought that if ssl was on, it should only be https… Unless my nginx config is wrong somewhere…

My Nginx config:

    server {
        listen       80;
        server_name  "";

# force redirect http to https
        rewrite ^ https://$http_host$request_uri? permanent;

# this is required to allow let's encrypt to get the ssl cert
        location ^~ /.well-known {
	    allow all;
	    default_type "text/plain";
	root /usr/share/nginx/html/.well-known;
}

}
    server {
        listen 443;
        ssl on;
        ssl_certificate /etc/letsencrypt/live/<server>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<server>/privkey.pem;
        server_name "";
        proxy_set_header X-Forwarded-For $remote_addr;

        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
        server_tokens off;

        location / {
            fastcgi_pass    127.0.0.1:8000;
            fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
            fastcgi_param   PATH_INFO           $fastcgi_script_name;

            fastcgi_param   SERVER_PROTOCOL        $server_protocol;
            fastcgi_param   QUERY_STRING        $query_string;
            fastcgi_param   REQUEST_METHOD      $request_method;
            fastcgi_param   CONTENT_TYPE        $content_type;
            fastcgi_param   CONTENT_LENGTH      $content_length;
            fastcgi_param   SERVER_ADDR         $server_addr;
            fastcgi_param   SERVER_PORT         $server_port;
            fastcgi_param   SERVER_NAME         $server_name;
            fastcgi_param   REMOTE_ADDR         $remote_addr;
            fastcgi_param   HTTPS               on;
            fastcgi_param   HTTP_SCHEME         https;

            access_log      /var/log/nginx/seahub.access.log;
            error_log       /var/log/nginx/seahub.error.log;
            fastcgi_read_timeout 36000;
        }
        location /seafhttp {
            rewrite ^/seafhttp(.*)$ $1 break;
            proxy_pass http://127.0.0.1:8082;
            client_max_body_size 0;
            proxy_connect_timeout  36000s;
            proxy_read_timeout  36000s;
            proxy_send_timeout  36000s;
	    proxy_request_buffering off;
            send_timeout  36000s;
        }
        location /media {
            root /home/seafile/seafile/seafile-server-latest/seahub;
        }
    }

Can anyone else confirm that the client can do http requests when ssl is on and the location in under 443?

on port 80 just listen to the neccesary letsencrypt requests:

location ‘/.well-known/acme-challenge’ {
default_type “text/plain”;
root /mnt/drive/certbot-webroot;
}

in firewall (eg. iptables) block the internal seafile ports 8082 and 8000 from external. you only need port 80 for letsencrypt and port 443 for seafile.

Ok. So i only have 22, 80 and 443 open in Ubuntu firewall

# ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
80                         ALLOW       Anywhere                  
80 (v6)                    ALLOW       Anywhere (v6)             

I can still see http requests if i change the server connection to http in the client

$ sudo netstat -taucp | grep 2135
tcp        0      0 <my ip>:37788      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40518      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37790      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40522      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40520      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40516      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37786      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37750      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40514      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37792      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37792      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37788      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40518      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37790      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40522      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40520      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:40516      <server>.:http ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37786      <server>:https ESTABLISHED 2135/seafile-applet

And if i change the connection to https in the client, i only see https requests

$ sudo netstat -taucp | grep 2135
tcp        0      0 <my ip>:37988      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37994      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37990      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37992      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37996      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37988      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37994      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37990      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37992      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37996      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37988      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37994      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37990      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37992      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37996      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37988      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37994      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37990      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37992      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37996      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37988      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37994      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37990      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37992      <server>:https ESTABLISHED 2135/seafile-applet
tcp        0      0 <my ip>:37996      <server>:https ESTABLISHED 2135/seafile-applet

So not sure why it’s still making http requests when i change the connection. I would have thought they would be blocked with the config i have.

no they will be redirected:

“# force redirect http to https
rewrite ^ https://$http_host$request_uri? permanent;”

to test, disable that redirection and try again. the client should not connect succesfulle to seafile anymore.

I have just done a small test to dump port 80, and i have set http in the client connection string.

Doing tcpflow -p -c port 80 shows HTTP/1.1 301 Moved Permanently. So yes, http is redirected to https.

However i have found another security flaw. When connecting over http, and then using the cloud file browser with an encrypted library. The password is shown in it’s raw form as password=<my password>

I would see that as a security flaw. Even after having rewrite ^ https://$http_host$request_uri? permanent;" in nginx, the client can still connect over http, which shows raw passwords. There needs to be a way of preventing the clients connecting over http, that re-write rule does not solve the issue.

Yes, only provide Let’s Encrypt challenge responses over port 80 and only provide seafile services over port 443/ssl. I use virtual hosts with apache so with Nginx server blocks should be the feature you are looking for.

Yes I can do that, just under the port 80 server block add return 301 https://$server_name$request_uri; that seems to block the client from connecting via http and it still allows Lets Encrypt because of:

        location ^~ /.well-known {
	    allow all;
	    default_type "text/plain";
		root /usr/share/nginx/html/.well-known;

I think the Seafile manual should specify to use return to 301 instead of redirect, i imagine people will want to block users from using http by default.