📜 ⬆️ ⬇️

Safe and smart web server on debian 7

The article is in the process of writing, but I am ready to listen to good advice and comments, and then add or correct the material.
First of all, this material is aimed at beginners and those who keep several sites on one VPS at the same time, and at the same time they want to have both a safe and smart web server.
As a web server, we will have a bunch:

Apache 2.2 + PHP 5.4.4 + MySQL 5.5 + NGINX 1.2.1 + eAccelerator + memcached + vsftpd 3.0.2 + exim.

All this miracle will turn on Debian 7.
')
Let's start.


So, first of all after installing the OS, perform:

apt-get update apt-get dist-upgrade 


Then one team put all the necessary software:
 apt-get install htop atop vsftpd exim4-base exim4-daemon-light mailutils rcconf apache2 apache2-mpm-itk nginx mysql-server-5.5 mysql-client-5.5 php5 php5-dev memcached libmysqlclient-dev apache2-utils libexpat1 ssl-cert libapache2-mod-php5 libapache2-mod-ruby php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-common php5-ming php5-mysql php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl make automake checkinstall gcc gzip libreadline-dev libssl-dev libncurses5-dev zlib1g-dev 


During the installation process, the system will ask you to invent and enter a password for the root user of the MySQL database, we enter.
After full installation of the software, proceed to the configuration. All our sites will be located in the directory / home / user_dir / site_site, but you can place them in any directory convenient for you. In the site directory we will have 3 subdirectories: tmp (for temporary files and session files), logs (site logs), public_html (site directory).

Create a user dapf with the same group, home directory and a ban on using the console:
 useradd dapf -b /home -m -U -s /bin/false 


Set dapf user password:
 passwd dapf 


Create user directories with permissions and groups:
 mkdir -p -m 755 /home/dapf/dapf.ru/public_html mkdir -p -m 777 /home/dapf/dapf.ru/logs mkdir -p -m 777 /home/dapf/dapf.ru/tmp chmod 755 /home chmod 755 /home/dapf chmod +t /home/dapf/dapf.ru/logs chmod +t /home/dapf/dapf.ru/tmp chown -R dapf:dapf /home/dapf 


Forbid the console to the user www-data:
 usermod -s /bin/false www-data 


Now we are going to configure Apache.
We include the modules we need:
 a2enmod ssl a2enmod rewrite a2enmod suexec a2enmod include 


The ports configuration in the /etc/apache2/ports.conf file is correct:
 nano /etc/apache2/ports.conf 


It is necessary to replace port 80 with 81 (since we will have nginx at 80m):
 NameVirtualHost *:81 Listen 81 


Since we have a weak VPS (256 MB of RAM), we need to configure /etc/apache2/apache2.conf
 nano /etc/apache2/apache2.conf 


Set the following values:
 KeepAlive Off StartServers 1 MinSpareServers 3 MaxSpareServers 6 ServerLimit 24 MaxClients 24 MaxRequestsPerChild 3000 


Now create a new VirtualHost (site):
 nano /etc/apache2/sites-available/dapf.ru 

 <VirtualHost *:81> ServerName www.dapf.ru ServerAlias dapf.ru ServerAdmin support@dapf.ru DocumentRoot "/home/dapf/dapf.ru/public_html" <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /home/dapf/dapf.ru/public_html/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> ErrorLog /home/dapf/dapf.ru/logs/errors.log LogLevel warn CustomLog /home/dapf/dapf.ru/logs/access.log combined AssignUserId www-data dapf php_admin_value open_basedir "/home/dapf/:." php_admin_value upload_tmp_dir "/home/dapf/dapf.ru/tmp" php_admin_value session.save_path "/home/dapf/dapf.ru/tmp" </VirtualHost> 


Thanks to apache2-mpm-itk, we have the ability to use the AssignUserId www-data dapf directive in the virtual host configs, which allows you to disable the web shell and edit our project files, except those with o + w rights. Those. apache will be able to calmly read the php file, execute it and send it to the browser, but will not be able to make changes to its contents, which will create certain problems for hackers. If you want to allow Apache to edit files, use dapf dapf instead of www-data dapf. The open_basedir, upload_tmp_dir, session.save_path directives exclude receiving sessions from a neighboring site and navigating above the user directory.

We include the site:
 a2ensite dapf.ru 


And restart the Apache:
 service apache2 restart 


With the apache finished, now we will configure nginx.
First, let's configure gzip compression, assign the user www-data and install 1 processor core.
 nano /etc/nginx/nginx.conf 

 user www-data; worker_processes 1; pid /var/run/nginx.pid; error_log /var/log/nginx/error.log; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; gzip_disable "msie6"; # gzip_vary on; gzip_proxied any; gzip_comp_level 7; #Level Compress gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/x-javascri$ ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } 


After we create a new config of our virtualhost:

 nano /etc/nginx/sites-enabled/dapf.ru 

 server { listen 80; server_name dapf.ru www.dapf.ru; access_log /var/log/nginx.access_log; location ~* .(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|swf|flv|html|htm|mp3|docx|xlsx)$ { root /home/dapf/dapf.ru/public_html/; error_page 404 = @fallback; index index.html index.php; access_log off; expires 30d; } location ~ /.ht { deny all; } location / { proxy_pass http://127.0.0.1:81/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-for $remote_addr; proxy_set_header Host $host; proxy_connect_timeout 60; proxy_send_timeout 90; proxy_read_timeout 90; proxy_redirect off; proxy_set_header Connection close; proxy_pass_header Content-Type; proxy_pass_header Content-Disposition; proxy_pass_header Content-Length; } location @fallback { proxy_pass http://127.0.0.1:81; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } } 


Now the Apache is responsible for all the dynamics, and for the statics of nginx, when an error 404 appears that can occur when using mod_rewrite (CNC), the @fallback function will be called, which will redirect the request for the Apache for verification.

Reboot nginx: service nginx restart

To configure FTP, edit the vsftpd config file
 nano /etc/vsftpd.conf 


Delete everything and paste the following settings:
 listen=YES anonymous_enable=NO local_enable=YES write_enable=YES pasv_min_port=50000 pasv_max_port=60000 dirmessage_enable=YES xferlog_enable=YES file_open_mode=0644 local_umask=022 connect_from_port_20=YES ascii_upload_enable=YES ascii_download_enable=YES ftpd_banner=Welcome to our FTP service. chroot_local_user=YES allow_writeable_chroot=YES secure_chroot_dir=/var/run/vsftpd pam_service_name=vsftpd rsa_cert_file=/etc/ssl/certs/vsftpd.pem 


This will allow anonymous users to log in, allow old FTP clients to be used, and also limit the movement of users to their home directory only.

Then you need to correct the /etc/pam.d/vsftpd file to enable FTP authorization for users who do not have access to the console.
 nano /etc/pam.d/vsftpd 


Find and comment the line: auth required pam_shells.so
 #auth required pam_shells.so 


Restart vsftpd and try to log in:
 service vsftpd restart 


If you have an error: 500 OOPS: vsftpd: refusing to run with the writable root inside chroot (), do not get upset - this is a bug vsftpd, and it is solved by a simple update, for this we do:
 echo "deb http://ftp.us.debian.org/debian jessie main contrib non-free" >> /etc/apt/sources.list aptitude update aptitude upgrade vsftpd echo "allow_writeable_chroot=YES" >> /etc/vsftpd.conf service vsftpd restart 


You may have to re-fix the vsftpd configs, but after restarting the service, everything will work fine.

Configure MySQL.
 nano /etc/mysql/my.cnf 


Set the following directive values:
 key_buffer = 16K max_allowed_packet = 1M thread_stack = 64K table_cache = 4 sort_buffer = 64K net_buffer_length = 2K 


If you are not using InnoDB tables, you can add the skip-innodb directive.

Next, create a user and its database by running the command:
 echo "CREATE USER '_'@'localhost' IDENTIFIED BY '_'; GRANT USAGE ON * . * TO '_'@'localhost' IDENTIFIED BY '_' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; CREATE DATABASE IF NOT EXISTS _ DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; ; GRANT ALL PRIVILEGES ON _ . * TO '_'@'localhost';" | mysql --user=root --password=__ mysql 


The values ​​of database_user_password_, username_mouse_p_ password we specify our own.

The main part of the work we have finished, now you need to configure PHP + eAccelerator + exim.

Let's start with the Exim settings, run:
 dpkg-reconfigure exim4-config 


Choose OK, then the internet site; you are using SMTP, you specify your System mail name (I have this dapf.ru ), you can leave the IP addresses just 127.0.0.1, then to taste, until you get to Root and postmaster mail recipient, we indicate your email address to which the letters will be returned.

Perform to check:
 echo "test" | mail -s Test @email.com 


If the letter has arrived, then everything is fine, if not, then go back and reconfigure Exim.
Now install eAccelerator.

We download the latest version at the moment and unpack:
 wget https://codeload.github.com/eaccelerator/eaccelerator/legacy.tar.gz/master -O ea.tar.gz tar xvfz ea.tar.gz 


Go to the source directory eaccelerator (I have this eaccelerator-eaccelerator-42067ac) and install:
 cd eaccelerator-eaccelerator-42067ac phpize ./configure make make install 


Create a directory for the eAccelerator cache
 mkdir -p /var/cache/eaccelerator chmod 0777 /var/cache/eaccelerator 


Editing the file php.ini
 nano /etc/php5/apache2/php.ini 


Here we need to add the settings of eAccelerator, sendmail, for which we have exim, security settings, etc.
Add before [PHP] settings for eAccelerator
 ; eAccelerator configuration ; Note that eAccelerator may also be installed as a PHP extension or as a zend_extension ; If you are using a thread safe build of PHP you must use ; zend_extension_ts instead of zend_extension extension = "eaccelerator.so" eaccelerator.shm_size = "16" eaccelerator.cache_dir = "/var/cache/eaccelerator" eaccelerator.enable = "1" eaccelerator.optimizer = "1" eaccelerator.check_mtime = "1" eaccelerator.debug = "0" eaccelerator.filter = "" eaccelerator.shm_max = "0" eaccelerator.shm_ttl = "0" eaccelerator.shm_prune_period = "0" eaccelerator.shm_only = "0" eaccelerator.compress = "1" eaccelerator.compress_level = "9" eaccelerator.allowed_admin_path = "/var/www/eaccelerator" 


Now uncomment the sendmail_path and specify the path to exim
 sendmail_path = /usr/sbin/exim -t 


Next, set the following settings:
 ;         display_errors =Off log_errors=On ;   disable_functions = exec,ini_get,ini_get_all,parse_ini_file,passthru,php_uname,popen,proc_open,shell_exec,show_source,system,dl, show_source, readfile, popen, cwd,getcwd ;     : diskfreespace, disk_free_space, disk_total_space, eval, fileperms, fopen, opendir, phpinfo, phpversion, posix_getpwuid, posix_getgrgid, posix_uname,   . ;  error_reporting = E_ALL & ~ E_NOTICE 


Do the rest of the PHP settings as you wish, there are a lot of manuals on this topic on the net.

I will not consider the SSH setting, but I’ll stop on the firewall, since in Debian, all connections are allowed by default.

Create the file my.iptables.rules
 nano /etc/my.iptables.rules 

 *filter -A INPUT -i lo -j ACCEPT -AINPUT -d 127.0.0.0/8 -jREJECT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A OUTPUT -j ACCEPT -A INPUT -p tcp --dport 80 -j ACCEPT -A INPUT -p tcp --dport 443 -j ACCEPT -A INPUT -p tcp --dport 20 -j ACCEPT -A INPUT -p tcp --dport 21 -j ACCEPT -A INPUT -p tcp --dport 50000 -j ACCEPT -A INPUT -p tcp --dport 60000 -j ACCEPT -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 -A INPUT -j REJECT -A FORWARD -j REJECT COMMIT 


Activate and save the rules:
 iptables-restore < /etc/my.iptables.rules iptables-save > /etc/iptables.rules 


Check with the command iptables –L

Prescribe the download in the / etc / network / interfaces file
 nano /etc/network/interfaces 


After iface lo inet loopback add
 pre-up iptables-restore < /etc/iptables.rules 


Save and reboot the VPS.

Source: https://habr.com/ru/post/226971/


All Articles