Skip to content

Instantly share code, notes, and snippets.

@lluis
Forked from descala/webserver_setup_web.rb
Created January 11, 2019 10:07
Show Gist options
  • Save lluis/f8ef74dedc9c6c1e4a35276248dbaea2 to your computer and use it in GitHub Desktop.
Save lluis/f8ef74dedc9c6c1e4a35276248dbaea2 to your computer and use it in GitHub Desktop.
Script to setup a shared web hosting instance on Debian Stretch
#!/usr/bin/ruby
# Script to setup a shared web hosting instance on Debian Stretch
# with SFTP, Apache, MariaDB, LetsEncrypt
# * Run this to install required packages
#
# apt install pwgen ruby mariadb-client mariadb-server php7.0 php7.0-mysql \
# apache2 libapache2-mod-php7.0 phpmyadmin libapache2-mpm-itk
# a2enmod rewrite
#
# * TODO setup stretch-backports repo for LetsEncrypt
#
# apt install -t stretch-backports python-certbot-apache
#
# * Edit /etc/ssh/sshd_config to force SFTP for users in sftp group
#
# Match Group sftp
# ChrootDirectory %h
# ForceCommand internal-sftp
# AllowTcpForwarding no
#
# groupadd sftp
require 'fileutils'
def prompt(*args)
print(*args)
STDIN.gets
end
# logrotate for access_log and error_log
unless File.exists?('/etc/logrotate.d/webserver')
logrotate = <<EOF
/var/www/*/logs/*log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
if /etc/init.d/apache2 status > /dev/null ; then \\
/etc/init.d/apache2 reload > /dev/null; \\
fi;
endscript
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \\
run-parts /etc/logrotate.d/httpd-prerotate; \\
fi; \\
endscript
}
EOF
File.write('/etc/logrotate.d/webserver', logrotate)
end
raise "Only one argument: the domain name without www" if ARGV.length != 1
cmds = []
web = ARGV[0]
user = web.gsub(/[^0-9A-Za-z]/, '_')
sql_user = user[0..15] # max 16
db = "#{user}_db1"
root = "/var/www"
home = "#{root}/#{web}"
htdocs = "#{home}/htdocs"
web_pass = `pwgen -N 1 -A -0 10`.chomp
sql_pass = `pwgen -N 1 -A 10`.chomp
ip = `dig +short myip.opendns.com @resolver1.opendns.com`.chomp
tmp = "/tmp/#{web}"
FileUtils.mkdir_p(tmp)
index = <<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>#{web}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="expires" content="0">
<style>
body { text-align: center; padding: 150px; }
h1 { font-size: 50px; }
body { font: 20px Helvetica, sans-serif; color: #333; }
article { display: block; text-align: left; width: 650px; margin: 0 auto; }
a { color: #dc8100; text-decoration: none; }
a:hover { color: #333; text-decoration: none; }
</style>
</head><body>
<h2>#{web}</h2>
</body></html>
EOF
File.write("#{tmp}/index.html",index)
conf = <<EOF
<VirtualHost *:80>
AssignUserId #{user} #{user}
ServerAdmin webmaster@#{web}
ServerName www.#{web}
ServerAlias #{web}
DocumentRoot #{home}/htdocs
ErrorLog #{home}/logs/error_log
TransferLog #{home}/logs/access_log
RewriteEngine On
# RewriteCond %{HTTP_HOST} !=''
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
</VirtualHost>
EOF
File.write("#{tmp}/#{web}.conf",conf)
if File.exists? "/etc/apache2/sites-available/#{web}.conf"
puts "/etc/apache2/sites-available/#{web}.conf already exists"
cmds << "echo #{user}:#{web_pass} | chpasswd"
else
cmds << "mkdir -p #{htdocs}"
cmds << "mkdir -p #{home}/logs"
cmds << "cp #{tmp}/index.html #{htdocs}"
cmds << "useradd -p '*' -G sftp -c 'Alta #{Time.now.strftime("%d/%m/%Y")}' -d #{home} -s /usr/sbin/nologin #{user}"
cmds << "chown -R #{user}:#{user} #{htdocs}"
cmds << "chown root:#{user} #{home}"
cmds << "chmod 750 #{home}"
cmds << "echo #{user}:#{web_pass} | chpasswd"
cmds << "cp #{tmp}/#{web}.conf /etc/apache2/sites-available/ "
cmds << "a2ensite #{web}.conf"
cmds << "apachectl configtest && service apache2 reload"
end
dades_web = <<EOF
*SFTP*
host = #{web}
user = #{user}
pass = #{web_pass}
EOF
if `mysql -uroot -e "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '#{db}'"` != ''
puts "mysql #{web} already exists"
end
mysql = <<EOF
CREATE DATABASE IF NOT EXISTS `#{db}`;
GRANT ALL ON `#{db}`.* TO '#{sql_user}'@'localhost' IDENTIFIED BY '#{sql_pass}';
EOF
File.write("#{tmp}/#{web}.sql", mysql)
cmds << "mysql < #{tmp}/#{web}.sql"
dades_sql = <<EOF
*MySQL*
host = localhost
db = #{db}
user = #{sql_user}
pass = #{sql_pass}
Admin URL http://#{web}/phpmyadmin o http://#{ip}/phpmyadmin
EOF
if File.exists? "/etc/apache2/sites-enabled/#{web}-le-ssl.conf"
puts "/etc/apache2/sites-available/#{web}-le-ssl.conf already exists. Skiping LetsEncrypt"
else
# TODO stdin and stdout get lost
# cmds << "certbot --apache -d #{web},www.#{web}"
end
if cmds.any?
puts "--"
puts cmds
puts "--"
prompt "Press enter (or ctrl+c to stop)"
puts 'Running commands ...'
cmds.each do |cmd|
puts cmd
`#{cmd}`
raise $?.to_s unless $?.success?
end
dades = <<EOF
#{dades_web}
#{dades_sql}
*Checks*
mysql #{db} -u#{sql_user} -p#{sql_pass}
https://#{web} http://#{web}
*TODO*
certbot --apache -d #{web},www.#{web}
EOF
puts dades
`rm #{tmp}/*`
else
puts 'Nothing to do'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment