23 Aug 2019 Matteo Mattei linux server ssh sftp If you have a linux server, openssh is almost always already present, so without any other tool you can configure a super secure SFTP chroot jail to allow your users to access the server limiting the visibility to their home directory.
Start creating a new linux system group called sftponly:
groupadd --system sftponly
We create a system group because we want an ID lower than 1000 so that every new user will take a sequential UID. Now open /etc/ssh/sshd_config and make sure to have the following lines:
PasswordAuthentication yes
ChallengeResponseAuthentication no
Now replace the line starting with Subsystem with the following:
Subsystem sftp internal-sftp
This line tells SSH to use its internal sftp subsytem to mange SFTP connections.
Now add the following lines at the bottom of the file:
Match Group sftponly
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
Basically the above section describes how to handle connections from users belonging to sftponly group. In particular we are telling SSH to chroot the users to their home directory, does not allow X11 and TCP forwarding and force to use the internal sftp interface.
After do that, restart ssh server to make the changes active:
Now the SFTP server is ready to be used but you must keep in mind some important rules otherwise it will not work!
- every user home directory must belong to root:root
- every user home directory must have 0755 permissions
- every user must belong to sftponly group
- every first level folder in user home directory must belong to ${USER}:sftponly
Let’s do an example: create a new user matteo with no login shell, assign it to sftpgroup group and set a password:
useradd --create-home --shell /usr/sbin/nologin --user-group matteo
usermod --groups sftponly matteo
passwd matteo
Assuming you want the following permissions:
mkdir /home/matteo/pics # write access by user matteo
mkdir /home/matteo/musics # write access by user matteo
mkdir /home/matteo/logs # read only access by user matteo
Configure the folders in this way:
chown root:root /home/matteo
chmod 755 /home/matteo
chown matteo:sftponly /home/matteo/pics
chown matteo:sftponly /home/matteo/musics
chown matteo:sftponly /home/matteo/logs
chmod 555 /home/matteo/logs
Now try with sftp command line client or with filezilla and test your new SFTP server. Files created from an SFTP session will belong to matteo:matteo.
As you can understand, this configuration is very useful for web servers running with PHP-FPM where every VirtualHost runs with its own user and privileges, so you can restrict the access by user with a secure SFTP connection and at the same time avoid all the problems related to the files permissions management and the configuration of a separated FTP/FTPS server.
I hope you enjoy this article. If you like it please leave a comment!
21 Aug 2019 Matteo Mattei linux server ssh rsyslog python In order to monitor SSH access we can rely on rsyslog given all SSH accesses are recorded in /var/log/auth.log. Start creating a custom rsyslog configuration /etc/rsyslog.d/90-ssh.conf
with the following content:
Basically we are telling rsyslog to look for lines where the program name is sshd and the message contains the session opened for user. Every time the above condition is matched, rsyslog will call the script we are going to create passing the entire log line as parameter.
Assuming we want to receive an email with the user that have been logged, open your editor and create the file /usr/local/bin/log_access.py
:
Make the file executable:
chmod +x /usr/local/bin/log_access.py
Remember to fill the SMTP data at the beginning of the script. As you can see the above script also logs all logins to /var/log/logins.log
.
Feel free to do what you want in the python script, the above it’s only an example!
Now restart rsyslog and try if everything works as expected.
/etc/init.d/rsyslog restart
Let me know your work cases and if this article can help you!
28 Jul 2019 Matteo Mattei linux server mariadb debian php iptables postfix ssl letsencrypt sftp Setup bash and update the system
cp /etc/skel/.bashrc /root/.bashrc
apt-get update
apt-get dist-upgrade
Make sure to have the following two lines (with the same format) at the top of your /etc/hosts file
127.0.0.1 localhost.localdomain localhost
xxx.xxx.xxx.xxx web1.myserver.com web1
Note: xxx.xxx.xxx.xxx is the public IP address assigned to your server.
Install all needed packages
apt install wget vim git acl screen rsync net-tools pwgen php mariadb-server mariadb-client apache2 iptables shorewall php php-cli php-curl php-dev php-gd php-imagick php-imap php-memcache php-pspell php-recode php-tidy php-xmlrpc php-pear php-fpm php-mbstring php-mysql postfix ca-certificates bsd-mailx
Postfix:
- Select Internet Site
- System mail name: (insert here the FQDN, for example web1.myserver.com)
Setup chrooted SFTP jail
Create sftponly
group:
addgroup --system sftponly
Edit /etc/ssh/sshd_config
and make sure to have the following lines:
PasswordAuthentication yes
ChallengeResponseAuthentication no
Then change the Subsystem line with the following:
Subsystem sftp internal-sftp
And create the section to allow chrooted SFTP access to the users belonging to the sftponly
group.
Match Group sftponly
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
Now restart ssh server:
In order to have a working sftp jail, there are 4 rules to follow:
- every user home directory must belong to root:root
- every user home directory must have 0755 permissions
- every user must belong to sftponly group
- every subfolder in user home directory must belong to ${USER}:sftponly
Setup Apache
Stop Apache web server:
Backup Apache configuration:
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.backup
Edit the following lines in /etc/apache2/apache2.conf
- From Timeout 300 to Timeout 45
- From KeepAliveTimeout 5 to KeepAliveTimeout 15
Create a configuration for phpmyadmin:
cat << EOF > /etc/apache2/conf-available/phpmyadmin.conf
Alias /phpmyadmin /usr/share/phpmyadmin
<Directory /usr/share/phpmyadmin>
Options SymLinksIfOwnerMatch
DirectoryIndex index.php
<IfModule mod_php5.c>
<IfModule mod_mime.c>
AddType application/x-httpd-php .php
</IfModule>
<FilesMatch ".+\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
php_value include_path .
php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/
php_admin_value mbstring.func_overload 0
</IfModule>
<IfModule mod_php.c>
<IfModule mod_mime.c>
AddType application/x-httpd-php .php
</IfModule>
<FilesMatch ".+\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
php_value include_path .
php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/
php_admin_value mbstring.func_overload 0
</IfModule>
</Directory>
# Authorize for setup
<Directory /usr/share/phpmyadmin/setup>
<IfModule mod_authz_core.c>
<IfModule mod_authn_file.c>
AuthType Basic
AuthName "phpMyAdmin Setup"
AuthUserFile /etc/phpmyadmin/htpasswd.setup
</IfModule>
Require valid-user
</IfModule>
</Directory>
# Disallow web access to directories that don't need it
<Directory /usr/share/phpmyadmin/templates>
Require all denied
</Directory>
<Directory /usr/share/phpmyadmin/libraries>
Require all denied
</Directory>
<Directory /usr/share/phpmyadmin/setup/lib>
Require all denied
</Directory>
EOF
Configure the proper Apache modules and configurations:
a2dismod mpm_worker
a2dismod mpm_prefork
a2enmod mpm_event
a2enmod ssl
a2enmod rewrite
a2enmod headers
a2enmod deflate
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_fcgi
a2enmod http2
a2enmod setenvif
a2enconf security
a2enconf php7.3-fpm
a2enconf phpmyadmin
Now restart Apache:
/etc/init.d/apache2 restart
Setup MariaDB
Secure MariaDB installation:
mysql_secure_installation
- Enter current password for root (enter for none): [ENTER]
- Set root password? [Y/n] Y
- Write your MARIAB_ROOT_PASSWORD
- Remove anonymous users? [Y/n] Y
- Disallow root login remotely? [Y/n] Y
- Remove test database and access to it? [Y/n] Y
- Reload privilege tables now? [Y/n] Y
Instruct MariaDB to use native password:
mysql -u root mysql -e "update user set plugin='mysql_native_password' where user='root'; flush privileges;"
Set MariaDB root password in a configuration file (the same password configured before!)
cat << EOF > /root/.my.cnf
[client]
user = root
password = MARIADB_ROOT_PASSWORD
EOF
Enable MySQL slow query logging (often useful during slow page load debugging):
sed -i "{s/^#slow_query_log_file /slow_query_log_file /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#long_query_time /long_query_time /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#log_slow_rate_limit /log_slow_rate_limit /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#log_slow_verbosity /log_slow_verbosity /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#log-queries-not-using-indexes/log-queries-not-using-indexes/g}" /etc/mysql/mariadb.conf.d/50-server.cnf
MySQL is now configured, so restart it:
/etc/init.d/mysql restart
Install phpMyAdmin
The version of phpmyadmin coming with the distribution is not updated so I prefer to install the latest manually:
export VER="5.0.4"
cd /tmp
wget https://files.phpmyadmin.net/phpMyAdmin/${VER}/phpMyAdmin-${VER}-all-languages.tar.gz
tar xvf phpMyAdmin-${VER}-all-languages.tar.gz
rm -f phpMyAdmin-${VER}-all-languages.tar.gz
mv phpMyAdmin* /usr/share/phpmyadmin
mkdir -p /var/lib/phpmyadmin/tmp
chown -R www-data:www-data /var/lib/phpmyadmin
mkdir /etc/phpmyadmin/
cp /usr/share/phpmyadmin/config.sample.inc.php /usr/share/phpmyadmin/config.inc.php
Now edit the file /usr/share/phpmyadmin/config.inc.php
and set secret passphrase and temporary directory:
// https://www.devglan.com/online-tools/bcrypt-hash-generator
$cfg['blowfish_secret'] = 'SECRET_HERE';
[...]
$cfg['TempDir'] = '/var/lib/phpmyadmin/tmp';
Copy the default configuration for one interface:
cd /usr/share/doc/shorewall/examples/one-interface
cp interfaces /etc/shorewall/
cp policy /etc/shorewall/
cp rules /etc/shorewall/
cp zones /etc/shorewall/
Now open /etc/shorewall/policy file and change the line:
removing info directive given it fills the system logs:
Now open /etc/shorewall/rules and add the following rules at the bottom of the file:
HTTP/ACCEPT net $FW
HTTPS/ACCEPT net $FW
SSH/ACCEPT net $FW
NOTE: in case you want to allow ICMP (Ping) traffic from a specific remote hosts you need to add a rule similar to the following where xxx.xxx.xxx.xxx is the remote IP address, before the Ping(DROP) rule:
Ping(ACCEPT) net:xxx.xxx.xxx.xxx $FW
Now edit /etc/default/shorewall and change startup=0 to startup=1 You are now ready to start the firewall:
/etc/init.d/shorewall start
Setup Postfix
Stop postfix server:
Edit /etc/mailname and set your server domain name, for example:
Restart Postfix:
/etc/init.d/postfix start
Let’s encrypt
In order to get SSL free certificates with let’s encrypt install the powerful (and simple) dehydrated tool:
cd /root
git clone https://github.com/lukas2511/dehydrated.git
cd dehydrated
touch domains.txt
cp docs/examples/config .
/root/dehydrated/dehydrated --register --accept-terms
Prepare Apache2 configuration for letsencrypt:
cat << EOF > /etc/apache2/conf-available/dehydrated.conf
Alias /.well-known/acme-challenge /var/www/dehydrated
<Directory /var/www/dehydrated>
Options None
AllowOverride None
# Apache 2.x
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
EOF
Enable new config and reload Apache
a2enconf dehydrated
systemctl reload apache2
Log rotation
In order to correctly log files you need to adjust logrotate configuration for Apache:
cat << EOF >> /etc/logrotate.d/apache2
/var/www/vhosts/*/logs/access*.log
{
rotate 30
missingok
size 10M
compress
delaycompress
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}
/var/www/vhosts/*/logs/error*.log
{
rotate 3
missingok
compress
delaycompress
size 2M
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}
EOF
Prepare environment
Create all needed directories and files
mkdir /root/cron_scripts
mkdir -p /var/www/vhosts
Now download all tools to manage the server locally:
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ADD_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ADD_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ADD_SSL.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ALIAS_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/DEL_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/DEL_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/DOMAIN_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/MYSQL_CREATE.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/UPDATE_SFTP_PASSWORD.sh
chmod 770 *.sh
Download also the tools that will be used with cron:
cd /root/cron_scripts
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/cron_scripts/backup_mysql.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/cron_scripts/mysql_optimize.sh
chmod 770 *.sh
- Edit /root/ADD_DOMAIN.sh and change ADMIN_EMAIL variable with your email address.
Edit /etc/crontab and add the following lines at the bottom:
# mysql optimize tables
3 4 * * 7 root /root/cron_scripts/mysql_optimize.sh
# mysql backup
32 4 * * * root /root/cron_scripts/backup_mysql.sh
# letsencrypt
50 2 * * * root /root/dehydrated/dehydrated -c > /dev/null
31 Dec 2017 Matteo Mattei linux server mariadb varnish debian php iptables postfix ssl letsencrypt Setup bash and update the system
cp /etc/skel/.bashrc /root/.bashrc
apt-get update
apt-get dist-upgrade
Make sure to have the following two lines (with the same format) at the top of your /etc/hosts file
127.0.0.1 localhost.localdomain localhost
xxx.xxx.xxx.xxx web1.myserver.com web1
Note: xxx.xxx.xxx.xxx is the public IP address assigned to your server.
Install all needed packages
apt-get install vim git acl screen rsync net-tools php mysql-server mysql-client apache2 iptables phpmyadmin varnish shorewall vsftpd php-cli php-curl php-dev php-gd php-imagick php-imap php-memcache php-pspell php-recode php-tidy php-xmlrpc php-pear postfix apg ca-certificates bsd-mailx
MariaDB/PhpMyAdmin:
- web server to reconfigure automatically: apache2
- configure database for phpmyadmin with dbconfig-common? Yes
- MySQL application password for phpmyadmin: [blank]
Postfix:
- Select Internet Site
- System mail name: (insert here the FQDN, for example web1.myserver.com)
Setup FTP
Stop VSFTP server:
Create backup configuration:
mv /etc/vsftpd.conf /etc/vsftpd.conf.backup
Add new configuration:
cat << "EOF" > /etc/vsftpd.conf
listen=YES
listen_port=21
anonymous_enable=NO
local_enable=YES
guest_enable=YES
guest_username=nobody
user_sub_token=$USER
local_root=/var/www/vhosts/$USER
virtual_use_local_privs=YES
user_config_dir=/etc/vsftpd/users
pam_service_name=vsftpd_local_and_virtual
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
ftpd_banner=Welcome to my ftp server
write_enable=YES
download_enable=YES
dirlist_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
xferlog_file=/var/log/xferlog
connect_from_port_20=YES
connect_timeout=60
data_connection_timeout=300
idle_session_timeout=300
local_max_rate=0
max_clients=0
max_per_ip=3
EOF
Create an empty chroot_list file:
mkdir /etc/vsftpd
touch /etc/vsftpd/chroot_list
Install PAM module for virtual users:
apt-get install libpam-pwdfile
And configure it creating the file /etc/pam.d/vsftpd_local_and_virtual
with this content:
# Standard behaviour for ftpd(8).
auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
# first try to authenticate local users
auth sufficient pam_unix.so
# if that failed, login with virtual user
auth required pam_pwdfile.so pwdfile /etc/vsftpd/passwd
# pam_pwdfile doesn't come with account, so we just permit on success
account required pam_permit.so
Start VSFTP server:
Setup Apache
Stop Apache web server:
Backup Apache configuration:
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.backup
Edit the following lines in /etc/apache2/apache2.conf
- From Timeout 300 to Timeout 45
- From KeepAliveTimeout 5 to KeepAliveTimeout 15
Edit /etc/apache2/mods-enabled/mpm_prefork.conf:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 10000
</IfModule>
Edit /etc/apache2/ports.conf and change the port 80 with 8080 since we are going to use Varnish:
Change the port (from 80 to 8080) also in the default virtual host /etc/apache2/sites-enabled/000-default.conf
Enable useful Apache modules:
a2enmod ssl
a2enmod rewrite
a2enmod headers
a2enmod deflate
a2enmod proxy
a2enmod proxy_http
Now restart Apache:
/etc/init.d/apache2 restart
Setup Varnish
Stop Varnish daemon:
Backup your /etc/varnish/default.vcl and create a new one with this content:
vcl 4.0;
import std;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
if (req.url ~ "^/phpmyadmin") {
return (pass);
}
if ((client.ip != "127.0.0.1" && std.port(server.ip) == 80) &&
(
(req.http.host ~ "localhost")
# ENSURE HTTPS - DO NOT REMOVE THIS LINE
)
){
set req.http.x-redir = "https://" + req.http.host + req.url;
return (synth(750, ""));
}
}
sub vcl_synth {
# Listen to 750 status from vcl_recv.
if (resp.status == 750) {
# Redirect to HTTPS with 301 status.
set resp.status = 301;
set resp.http.Location = req.http.x-redir;
return(deliver);
}
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
}
Now edit /etc/default/varnish and set the DAEMON_OPTS variable like this:
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"
Now we have to make some changes also to systemd scripts (this step is mandatory for Debian Stretch!) since systemd does not consider /etc/default/varnish settings.
Edit /lib/systemd/system/varnish.service and change port 6081 with port 80:
[Unit]
Description=Varnish HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/4.1/ man:varnishd
[Service]
Type=simple
LimitNOFILE=131072
LimitMEMLOCK=82000
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
Restart Varnish:
systemctl daemon-reload
systemctl restart varnish.service
Setup MariaDB
Secure MariaDB installation:
mysql_secure_installation
- Enter current password for root (enter for none): [ENTER]
- Set root password? [Y/n] Y
- Write your MARIAB_ROOT_PASSWORD
- Remove anonymous users? [Y/n] Y
- Disallow root login remotely? [Y/n] Y
- Remove test database and access to it? [Y/n] Y
- Reload privilege tables now? [Y/n] Y
Instruct MariaDB to use native password:
mysql -u root mysql -e "update user set plugin='mysql_native_password' where user='root'; flush privileges;"
Set MariaDB root password in a configuration file (the same password configured before!)
cat << EOF > /root/.my.cnf
[client]
user = root
password = MARIADB_ROOT_PASSWORD
EOF
Enable MySQL slow query logging (often useful during slow page load debugging):
sed -i "{s/^#slow_query_log_file /slow_query_log_file /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#long_query_time /long_query_time /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#log_slow_rate_limit /log_slow_rate_limit /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#log_slow_verbosity /log_slow_verbosity /g}" /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "{s/^#log-queries-not-using-indexes/log-queries-not-using-indexes/g}" /etc/mysql/mariadb.conf.d/50-server.cnf
MySQL is now configured, so restart it:
/etc/init.d/mysql restart
Fix for PhpMyAdmin redirecting to port 8080
If you try to access to http://yoursitename/phpmyadmin you are redirected to http://yoursitename:8080/phpmyadmin that will not work unless you open the firewall rule for port 8080 as described below. This because the web server is actually running on port 8080. To workaround this and have the PhpMyAdmin working on port 80 you need to force the redirect:
cat << "EOF" > /etc/phpmyadmin/conf.d/fix-redirection.php
<?php
$cfg['PmaAbsoluteUri'] = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].'/phpmyadmin';
EOF
Copy the default configuration for one interface:
cd /usr/share/doc/shorewall/examples/one-interface
cp interfaces /etc/shorewall/
cp policy /etc/shorewall/
cp rules /etc/shorewall/
cp zones /etc/shorewall/
cd /usr/share/doc/shorewall6/examples/one-interface
cp interfaces /etc/shorewall6/
cp policy /etc/shorewall6/
cp rules /etc/shorewall6/
cp zones /etc/shorewall6/
Now open /etc/shorewall/policy file and change the line:
removing info directive given it fills the system logs:
Now open /etc/shorewall/rules and add the following rules at the bottom of the file:
HTTP/ACCEPT net $FW
HTTPS/ACCEPT net $FW
SSH/ACCEPT net $FW
FTP/ACCEPT net $FW
# real apache since varnish listens on port 80
#ACCEPT net $FW tcp 8080
NOTE: in case you want to allow ICMP (Ping) traffic from a specific remote hosts you need to add a rule similar to the following where xxx.xxx.xxx.xxx is the remote IP address, before the Ping(DROP) rule:
Ping(ACCEPT) net:xxx.xxx.xxx.xxx $FW
Now edit /etc/default/shorewall and change startup=0 to startup=1 You are now ready to start the firewall:
/etc/init.d/shorewall start
Setup Postfix
Stop postfix server:
Edit /etc/mailname and set your server domain name, for example:
Then, in order to monitor mail traffic coming from PHP you need to edit /etc/php/7.0/apache2/php.ini. Go to [mail function] section and set the following two options:
sendmail_path = /usr/local/bin/sendmail-wrapper
auto_prepend_file = /usr/local/bin/env.php
Now create the two files above in /usr/local/bin:
sendmail-wrapper:
#!/bin/sh
logger -p mail.info sendmail-wrapper.sh: site=${HTTP_HOST}, client=${REMOTE_ADDR}, script=${SCRIPT_NAME}, pwd=${PWD}, uid=${UID}, user=$(whoami)
/usr/sbin/sendmail -t -i $*
env.php:
<?php
putenv("HTTP_HOST=".@$_SERVER["HTTP_HOST"]);
putenv("SCRIPT_NAME=".@$_SERVER["SCRIPT_NAME"]);
putenv("SCRIPT_FILENAME=".@$_SERVER["SCRIPT_FILENAME"]);
putenv("DOCUMENT_ROOT=".@$_SERVER["DOCUMENT_ROOT"]);
putenv("REMOTE_ADDR=".@$_SERVER["REMOTE_ADDR"]);
?>
Now make they both have executable flag:
chmod +x /usr/local/bin/sendmail-wrapper
chmod +x /usr/local/bin/env.php
Add also /usr/local/bin/ to the open_basedir php list in /etc/apache2/conf-enabled/phpmyadmin.conf
php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/local/bin/
Restart Postfix:
/etc/init.d/postfix start
Let’s encrypt
In order to SSL free certificates with let’s encrypt install the powerful (and simple) dehydrated tool:
cd /root
git clone https://github.com/lukas2511/dehydrated.git
cd dehydrated
touch domains.txt
cp docs/examples/config .
Prepare Apache2 configuration for letsencrypt:
cat << EOF > /etc/apache2/conf-available/dehydrated.conf
Alias /.well-known/acme-challenge /var/www/dehydrated
<Directory /var/www/dehydrated>
Options None
AllowOverride None
# Apache 2.x
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
EOF
Enable new config and reload Apache
a2enconf dehydrated
systemctl reload apache2
Log rotation
In order to correctly log files you need to adjust lograte configuration for Apache:
cat << EOF >> /etc/logrotate.d/apache2
/var/www/vhosts/*/logs/access*.log
{
rotate 30
missingok
size 10M
compress
delaycompress
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}
/var/www/vhosts/*/logs/error*.log
{
rotate 3
missingok
compress
delaycompress
size 2M
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}
EOF
Prepare environment
Create all needed directories and files
mkdir /root/cron_scripts
mkdir -p /var/www/vhosts
mkdir -p /etc/vsftpd/users
touch /etc/vsftpd/passwd
Now download all tools to manage the server locally:
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_FTP_VIRTUAL_USER.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_SSL.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ALIAS_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/CLEAN_VARNISH_CACHE.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DEL_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DEL_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DEL_FTP_VIRTUAL_USER.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DOMAIN_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/MYSQL_CREATE.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/UPDATE_ALL_FTP_PASSWORD.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/UPDATE_FTP_PASSWORD.sh
chmod 770 *.sh
Download also the tools that will be used with cron:
cd /root/cron_scripts
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/cron_scripts/backup_mysql.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/cron_scripts/mysql_optimize.sh
chmod 770 *.sh
- Edit /root/ADD_DOMAIN.sh and change ADMIN_EMAIL variable with your email address.
Edit /etc/crontab and add the following lines at the bottom:
# mysql optimize tables
3 4 * * 7 root /root/cron_scripts/mysql_optimize.sh
# mysql backup
32 4 * * * root /root/cron_scripts/backup_mysql.sh
# letsencrypt
50 2 * * * root /root/dehydrated/dehydrated -c > /dev/null
13 Sep 2016 Matteo Mattei raspberrypi backup When I backup my raspberry pi SD card one problem I always faced is how much storage space I have to use because using dd command the resulting backup image is exactly the same size of the whole SD card and having memory cards of 32GB or more, the storage of my pc would end pretty soon.
That said I wrote a little script that takes the big image, resize it to the minimal and compress it using gzip.
Just for completeness, this is the command I use to create the image of the SD card:
sudo dd if=/dev/mmcblk0 of=/path/to/image.img bs=1M
Now you can use the following script to shrink the image:
sudo ./raspberrypi_image_resize.sh /path/to/image.img
The process takes some time and at the end you will find that the size of the compressed image is drastically reduced. This is an example of a 8GB SD card before and after the compression:
-rw-r--r-- 1 matteo matteo 8026849280 Sep 10 15:45 image.img
-rw-r--r-- 1 matteo matteo 468097056 Sep 12 12:57 image.img.gz
So from a 8GB file, we have obtained 460MB file.