{"id":1608,"date":"2017-02-17T09:25:01","date_gmt":"2017-02-17T09:25:01","guid":{"rendered":"http:\/\/cdblog.cdstealer.com\/?p=1608"},"modified":"2023-07-27T06:27:32","modified_gmt":"2023-07-27T05:27:32","slug":"vsftpd","status":"publish","type":"post","link":"https:\/\/cdblog.cdstealer.com\/?p=1608","title":{"rendered":"VSFTPD"},"content":{"rendered":"\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"494\" height=\"129\" src=\"http:\/\/cdblog.cdstealer.com\/wp-content\/uploads\/2017\/02\/vsftpd-1.png\" alt=\"\" class=\"wp-image-1614\" srcset=\"https:\/\/cdblog.cdstealer.com\/wp-content\/uploads\/2017\/02\/vsftpd-1.png 494w, https:\/\/cdblog.cdstealer.com\/wp-content\/uploads\/2017\/02\/vsftpd-1-300x78.png 300w\" sizes=\"auto, (max-width: 494px) 100vw, 494px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Here I will show how to configure VSFTPD for basic authentication so that we have a base working daemon. &nbsp;Then we will build on that by implementing SSL and then virtual users.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Obviously first thing is first ;) &nbsp;If you haven't already, install vsftpd.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">emerge -av vsftpd\n...\nnet-ftp\/vsftpd-3.0.2-r1::gentoo USE=\"pam ssl tcpd -caps (-selinux) -xinetd\"<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We want to enable <strong>pam<\/strong> and <strong>ssl<\/strong> for later on. &nbsp;Once done, pop this into \/etc\/vsftpd\/vsftpd.conf<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">##################\n# Basic Settings #\n##################\nanonymous_enable=NO\ndirmessage_enable=YES\nxferlog_enable=YES\nvsftpd_log_file=\/var\/log\/vsftpd.log\nconnect_from_port_20=YES\nxferlog_file=\/var\/log\/vsftpd.log\ndata_connection_timeout=120\nnopriv_user=ftp\nftpd_banner=Insert Welcome Message\nlisten=YES\nlisten_address=&lt;server IP&gt;\nlisten_port=21\n\n###############\n# Local Users #\n###############\nlocal_enable=YES\nwrite_enable=YES\nchroot_local_user=YES\npasswd_chroot_enable=YES\nallow_writeable_chroot=NO\nuserlist_enable=YES\nuserlist_deny=NO\nuserlist_file=\/etc\/vsftpd\/vsftpd.user_list<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The above will tell vsftpd to not allow any anonymous connections eg mandatory login. &nbsp;What and where to log. What IP and port to listen on. &nbsp;To lock users into their home directory (defined in \/etc\/passwd).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The bottom 3 lines&nbsp;<strong>userlist_*<\/strong> we define so we don't grant all local users ftp access. &nbsp;If you answer YES to <strong>userlist_deny<\/strong>, the user list will deny any users listed in the file and allow everything else.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cat \/etc\/vsftpd\/vsftpd.user_list\nuser1\nuser2\nuser3<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart vsftpd to activate the new config.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let's test and make sure everything is working.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ ftp cdstealer.com\nConnected to cdstealer.com (&lt;IP&gt;).\n220 (vsFTPd 3.0.2)\nName (cdstealer.com:user1): \n530 Please login with USER and PASS.\nSSL not available\n331 Please specify the password.\nPassword:\n230 Login successful.\nRemote system type is UNIX.\nUsing binary mode to transfer files.\nftp&gt;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">SSL<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">So let's get some encryption so we aren't transmitting plain text credentials.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generate a self signed cert.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout \/etc\/ssl\/apache2\/vsftp.pem -out \/etc\/ssl\/apache2\/vsftp.pem\nGenerating a 4096 bit RSA private key\n..........................................................................................++\n....++\nwriting new private key to '\/etc\/ssl\/apache2\/vsftp.pem'\n-----\nYou are about to be asked to enter information that will be incorporated\ninto your certificate request.\nWhat you are about to enter is what is called a Distinguished Name or a DN.\nThere are quite a few fields but you can leave some blank\nFor some fields there will be a default value,\nIf you enter '.', the field will be left blank.\n-----\nCountry Name (2 letter code) [AU]:GB\nState or Province Name (full name) [Some-State]:Somewhere nice\nLocality Name (eg, city) []:Leeds\nOrganization Name (eg, company) [Internet Widgits Pty Ltd]:cdstealer.com\nOrganizational Unit Name (eg, section) []:\nCommon Name (e.g. server FQDN or YOUR name) []:cdstealer.com\nEmail Address []:<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The openssl command I've used, generates a 4096bit encrypted cert (this is good) that is valid for 10 years. :)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Execute the following to remove unwanted access to the cert.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">chmod 600 \/etc\/ssl\/apache2\/vsftp.pem<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add this section to your \/etc\/vsftpd\/vsftpd.conf file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">##############<br># Enable SSL #<br>##############<br>ssl_enable=YES<br>allow_anon_ssl=NO<br>force_local_data_ssl=YES<br>force_local_logins_ssl=YES<br>require_ssl_reuse=NO<br>ssl_tlsv1=NO<br>ssl_sslv2=NO<br>ssl_sslv3=NO<br>implicit_ssl=NO<br>ssl_ciphers=TLSv1.2+HIGH:TLSv1.3+HIGH:@STRENGTH:!eNULL:!aNULL<br>rsa_cert_file=\/etc\/letsencrypt\/live\/cdstealer.com\/fullchain.pem<br>rsa_private_key_file=\/etc\/letsencrypt\/live\/cdstealer.com\/privkey.pem<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart&nbsp;vsftpd to activate the new config.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let's test and make sure everything is still working.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ ftp cdstealer.com\nConnected to cdstealer.com (&lt;IP&gt;).\n220 (vsFTPd 3.0.2)\nName (cdstealer.com:user1): \n234 Proceed with negotiation.\n[SSL Cipher AES128-SHA]\n331 Please specify the password.\nPassword:\n230 Login successful.\nRemote system type is UNIX.\nUsing binary mode to transfer files.\nftp&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">GREAT! &nbsp;So now we have a secure FTP service running.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Extra Options:<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">##################\n# Other Settings #\n##################\ndirlist_enable=YES\ndownload_enable=YES\nforce_dot_files=NO\nhide_ids=YES\nmax_clients=2\nmax_per_ip=2\n\n#######################\n# Passive Connections #\n#######################\npasv_enable=YES\npasv_address=&lt;domainname&gt;\npasv_min_port=63899\npasv_max_port=63999\npasv_addr_resolve=YES<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Virtual Users:<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the interest of security, I'm not comfortable having system user accounts, even though we have secured things with only specific users able to ftp. &nbsp;I believe that standard ftp authentication does not support encryption for system users, but does for virtual users?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is a little more involved than having standard system users :(<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, add the following to your \/etc\/vsftpd\/vsftpd.conf file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">##################\n## Virtual Users #\n##################\nvirtual_use_local_privs=YES\npam_service_name=vsftpd\nuser_sub_token=$USER\nlocal_root=\/FTP\/$USER\nsecure_chroot_dir=\/var\/run\/vsftpd\nguest_enable=YES\nguest_username=ftp\nuser_config_dir=\/etc\/vsftpd\/virtualUsers<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here we define that virtual users get the same permissions as the ftp system user, are unable to browse outside their directory, use a PAM database for credentials and define custom settings per user.<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">Create the PAM config.<\/h6>\n\n\n\n<pre class=\"wp-block-preformatted\">vi \/etc\/pam.d\/vsftpd<\/pre>\n\n\n\n<h6 class=\"wp-block-heading\">Populate with the following.<\/h6>\n\n\n\n<pre class=\"wp-block-preformatted\">auth required \/lib\/security\/pam_userdb.so db=\/etc\/vsftpd\/virtualUsers\naccount required \/lib\/security\/pam_userdb.so db=\/etc\/vsftpd\/virtualUsers\nsession required \/lib\/security\/pam_loginuid.so<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">pam_userdb.so is part of pam, so nothing else to do.<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">Create user database.<\/h6>\n\n\n\n<pre class=\"wp-block-preformatted\">cd \/etc\/vsftpd\nvi virtualUsers.txt<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The format of this file is:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">username\npassword\nusername\npassword\n&lt;empty line&gt;<\/pre>\n\n\n\n<h6 class=\"wp-block-heading\">Execute the following to create the database.<\/h6>\n\n\n\n<pre class=\"wp-block-preformatted\">db5.3_load -T -t hash -f \/etc\/vsftpd\/virtualUsers.txt \/etc\/vsftpd\/virtualUsers.db<\/pre>\n\n\n\n<h6 class=\"wp-block-heading\">Update the permissions.<\/h6>\n\n\n\n<pre class=\"wp-block-preformatted\">chmod 600 virtualUsers.txt&nbsp;virtualUsers.db<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">NOTE: You may notice that the file extension is missing from the path in \/etc\/pam.d\/vsftpd. &nbsp;This is intentional as PAM automatically adds the .db suffix.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You will need to add the users from the database to the access list file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/etc\/vsftpd\/vsftpd.user_list<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For your convenience, I've written a user management script, <a href=\"http:\/\/cdstealer.com\/filez\/blog\/virtualUsers.sh\" target=\"_blank\" rel=\"noopener\">here<\/a> :)<\/p>\n\n\n\n<h6 class=\"wp-block-heading\">Define custom settings.<\/h6>\n\n\n\n<p class=\"wp-block-paragraph\">Create the directory which will store the configs. &nbsp;We defined this earlier as&nbsp;user_config_dir=\/etc\/vsftpd\/virtualUsers.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir&nbsp;\/etc\/vsftpd\/virtualUsers<\/pre>\n\n\n\n<h6 class=\"wp-block-heading\">Create a user config.<\/h6>\n\n\n\n<pre class=\"wp-block-preformatted\">vi \/etc\/vsftpd\/virtualUsers\/user1\n\nwrite_enable=NO\nlocal_root=\/FTP\/user1\nchroot_local_user=YES\ndirlist_enable=YES\ndownload_enable=YES<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here we set the users CHROOT directory, deny write permissions and allow downloading. &nbsp;Options here (not all) override specific options defined in the main config.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"http:\/\/vsftpd.beasts.org\/vsftpd_conf.html\" target=\"_blank\" rel=\"noopener\">RTFM<\/a><\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">NOTES:<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you get the following when logging in or listing a directory, it maybe due to the user directory not existing or not having permission.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssl_getc: SSL_read failed -1 = 0\n421 Service not available, remote server has closed connection\nLogin failed.\nNo control connection for command: Success<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">The following error may occur on ftp clients with vsftpd 3.0.x:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">500 OOPS: priv_sock_get_cmd<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is caused by seccomp filter sanboxing, which is enabled by default on amd64. To workaround this issue, disable seccomp filter sanboxing:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Add the following line to \/etc\/vsftpd\/vsftpd.conf.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">seccomp_sandbox=NO<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Don't forget to restart vsftpd :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here I will show how to configure VSFTPD for basic authentication so that we have a base working daemon. &nbsp;Then we will build on that by implementing SSL and then virtual users. Obviously first thing is first ;) &nbsp;If you haven't already, install vsftpd. emerge -av vsftpd ... net-ftp\/vsftpd-3.0.2-r1::gentoo USE=\"pam ssl tcpd -caps (-selinux) -xinetd\" &hellip; <a href=\"https:\/\/cdblog.cdstealer.com\/?p=1608\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">VSFTPD<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[278,97,18,44,277,276],"class_list":["post-1608","post","type-post","status-publish","format-standard","hentry","category-gentoo","tag-chroot","tag-ftp","tag-linux","tag-ssl","tag-virtual-users","tag-vsftpd"],"_links":{"self":[{"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=\/wp\/v2\/posts\/1608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1608"}],"version-history":[{"count":17,"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=\/wp\/v2\/posts\/1608\/revisions"}],"predecessor-version":[{"id":2398,"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=\/wp\/v2\/posts\/1608\/revisions\/2398"}],"wp:attachment":[{"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cdblog.cdstealer.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}