Last active
July 24, 2017 20:57
-
-
Save SirNeural/d8b5372a08c24f9fbfa1d77fefdfecc2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Check if using bash | |
| if [ ! "$BASH_VERSION" ] ; then | |
| echo "Please do not use sh to run this script ($0), just execute it directly with bash" 1>&2 | |
| exit 1 | |
| fi | |
| # Set variables | |
| read -p "Username: " USERNAME | |
| read -s -p "Primary Password: " PASSWORD | |
| echo | |
| read -s -p "Repeat Primary Password: " PASSWORD | |
| echo | |
| read -s -p "Htpasswd Password: " HTPASSWORD | |
| echo | |
| read -s -p "Repeat Htpasswd Password: " HTPASSWORD | |
| echo | |
| read -p "Project Name: " PROJECT | |
| read -p "URL: (example.com) " URL | |
| SYNCPORT='9024' | |
| # Add the syncthing release PGP keys: | |
| curl -s https://syncthing.net/release-key.txt | apt-key add - | |
| # Add the "release" channel to your APT sources: | |
| echo "deb http://apt.syncthing.net/ syncthing release" | tee /etc/apt/sources.list.d/syncthing.list | |
| # Find IP Address | |
| IP="" | |
| if [ -f /usr/bin/ec2metadata ] | |
| then | |
| IP=`timeout 1 ec2metadata --public-hostname` | |
| fi | |
| if [ "$IP" = "unavailable" ] | |
| then | |
| IP=`curl http://ipinfo.io/ip 2>/dev/null | egrep -o "[0-9\.]*"` | |
| fi | |
| if [ "$IP" = "" ] | |
| then | |
| IP=`ifconfig | perl -ple 'print $_ if /inet addr/ and $_ =~ s/.*inet addr:((?:\d+\.){3}\d+).*/$1/g ;$_=""' | grep -v ^\s*$ | grep -v 127.0.0.1 | head -n 1` | |
| fi | |
| if [ "$IP" = "" ] | |
| then | |
| IP=`cat /etc/hostname | head -n 1` | |
| fi | |
| # Create project folder, written in 4 single mkdir-statements to make sure this runs everywhere without problems | |
| mkdir "/var/www" | |
| mkdir "/var/www/html" | |
| # Update repositories | |
| apt update | |
| apt -y upgrade | |
| # Add repositories | |
| apt -y install python-software-properties | |
| add-apt-repository -y ppa:rwky/redis | |
| apt update | |
| # Set firewall options | |
| ufw allow ssh | |
| ufw allow 80/tcp | |
| ufw allow 443/tcp | |
| ufw allow 587/tcp | |
| ufw allow 1723/tcp | |
| ufw allow $SYNCPORT/tcp | |
| ufw allow 22000/tcp | |
| ufw allow 21027/udp | |
| sed -ie 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw | |
| sed -i "1i# START OPENVPN RULES\n# NAT table rules\n*nat\n:POSTROUTING ACCEPT [0:0]\n# Allow traffic from OpenVPN client to eth0\n\n-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE\nCOMMIT\n# END OPENVPN RULES\n" /etc/ufw/before.rules | |
| sed -i "29i# allow GRE protocol for VPN\n-A ufw-before-input -p 47 -j ACCEPT\n" /etc/ufw/before.rules | |
| echo "y" | ufw enable | |
| # Set configuration options | |
| debconf-set-selections <<< "mysql-server mysql-server/root_password password $PASSWORD" | |
| debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $PASSWORD" | |
| apt install -y nginx mysql-server php-fpm php-mysql php-mbstring php-gettext php-mcrypt php-curl php-cli php-zip redis-server php-redis php-libsodium | |
| # Change PHP-FPM settings | |
| sed -i '/cgi.fix_pathinfo=1/c cgi.fix_pathinfo=0' /etc/php/7.0/fpm/php.ini | |
| sed -i '/max_execution_time = 30/c max_execution_time = 300' /etc/php/7.0/fpm/php.ini | |
| sed -i '/upload_max_filesize = 2M/c upload_max_filesize = 8M' /etc/php/7.0/fpm/php.ini | |
| sed -i '/listen = 127.0.0.1:9000/c listen = /var/run/php/php7.0-fpm.sock' /etc/php/7.0/fpm/pool.d/www.conf | |
| # Create database | |
| echo "CREATE DATABASE ${PROJECT,,}" | mysql -uroot -p$PASSWORD | |
| # Enable PHP7 Mods | |
| phpenmod mcrypt | |
| # Install PHPMyAdmin | |
| debconf-set-selections <<< "phpmyadmin phpmyadmin/dbconfig-install boolean true" | |
| debconf-set-selections <<< "phpmyadmin phpmyadmin/app-password-confirm password $PASSWORD" | |
| debconf-set-selections <<< "phpmyadmin phpmyadmin/mysql/admin-pass password $PASSWORD" | |
| debconf-set-selections <<< "phpmyadmin phpmyadmin/mysql/app-pass password $PASSWORD" | |
| debconf-set-selections <<< "phpmyadmin phpmyadmin/reconfigure-webserver multiselect none" | |
| apt -y install phpmyadmin | |
| # Install miscellaneous packages | |
| apt -y install openssl git curl zip screen syncthing apache2-utils | |
| # Install Composer | |
| curl -s https://getcomposer.org/installer | php | |
| mv composer.phar /usr/local/bin/composer | |
| # Install Laravel | |
| composer global require "laravel/installer" | |
| PATH=~/.composer/vendor/bin:$PATH | |
| # Setup a new project | |
| cd /var/www/html | |
| laravel new ${PROJECT,,} | |
| chown -R www-data ${PROJECT,,}/storage | |
| chown -R www-data ${PROJECT,,}/bootstrap/cache | |
| chmod -R 755 ${PROJECT,,}/storage | |
| chmod -R 755 ${PROJECT,,}/bootstrap/cache | |
| # Install Project Dependencies | |
| cd ${PROJECT,,} | |
| composer require "laravelcollective/html" \ | |
| "laravel/tinker" \ | |
| "spatie/laravel-backup" \ | |
| "tymon/jwt-auth" \ | |
| "half2me/curlx" \ | |
| "guzzlehttp/guzzle" \ | |
| "anhskohbo/no-captcha" \ | |
| "pragmarx/google2fa" \ | |
| "bacon/bacon-qr-code":"~1.0" \ | |
| "snowfire/beautymail" \ | |
| "cmgmyr/messenger" \ | |
| "olssonm/l5-zxcvbn" \ | |
| "torann/geoip" \ | |
| "gloudemans/shoppingcart" | |
| # Register service provider and add alias | |
| sed -i "s/'name' => 'Laravel',/'name' => '${PROJECT}',/g" /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "s/'timezone' => 'UTC',/'timezone' => 'America\\/Phoenix',/g" /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tLaravel\\\Tinker\\\TinkerServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tTymon\\\JWTAuth\\\Providers\\\JWTAuthServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tCollective\\\Html\\\HtmlServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tSpatie\\\Backup\\\BackupServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tOlssonm\\\Zxcvbn\\\ZxcvbnServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tCmgmyr\\\Messenger\\\MessengerServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tAnhskohbo\\\NoCaptcha\\\NoCaptchaServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tSnowfire\\\Beautymail\\\BeautymailServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tPragmaRX\\\Google2FA\\\Vendor\\\Laravel\\\ServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tTorann\\\GeoIP\\\GeoIPServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/Illuminate\\\Auth\\\AuthServiceProvider::class,/a \\\tGloudemans\\\Shoppingcart\\\ShoppingcartServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'Html' => Collective\\\Html\\\HtmlFacade::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'Zxcvbn' => Olssonm\\\Zxcvbn\\\Facades\\\Zxcvbn::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'JWTAuth' => Tymon\\\JWTAuth\\\Facades\\\JWTAuth::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'JWTFactory' => Tymon\\\JWTAuth\\\Facades\\\JWTFactory::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'Google2FA' => PragmaRX\\\Google2FA\\\Vendor\\\Laravel\\\Facade::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'Messenger' => Cmgmyr\\\Messenger\\\MessengerServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'NoCaptcha' => Anhskohbo\\\NoCaptcha\\\Facades\\\NoCaptcha::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'BeautyMail' => Snowfire\\\Beautymail\\\BeautymailServiceProvider::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'GeoIP' => Torann\\\GeoIP\\\Facades\\\GeoIP::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "/'App' => Illuminate\\\Support\\\Facades\\\App::class,/a \\\t'Cart' => Gloudemans\\\Shoppingcart\\\Facades\\\Cart::class," /var/www/html/${PROJECT,,}/config/app.php | |
| sed -i "s/'name' => 'Example',/'name' => env('APP_NAME', 'admin@${URL}'),/g" /var/www/html/${PROJECT,,}/config/mail.php | |
| sed -i "s/'address' => 'hello@example.com',/'address' => env('APP_EMAIL', '${PROJECT}'),/g" /var/www/html/${PROJECT,,}/config/mail.php | |
| # Publish config file | |
| php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" | |
| php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider" | |
| php artisan vendor:publish --provider="Snowfire\Beautymail\BeautymailServiceProvider" | |
| php artisan vendor:publish --provider="Cmgmyr\Messenger\MessengerServiceProvider" | |
| php artisan vendor:publish --provider="Torann\GeoIP\GeoIPServiceProvider" --tag=config | |
| php artisan jwt:generate | |
| php artisan geoip:update | |
| # Run setup for syncthing | |
| syncthing -generate="/root/.config/syncthing" | |
| # Replace default configuration | |
| sed -e "s/<gui enabled=\"true\" tls=\"false\">/<gui enabled=\"true\" tls=\"true\">/g" /root/.config/syncthing/config.xml > /root/.config/syncthing/config.xml.tmp && mv /root/.config/syncthing/config.xml.tmp /root/.config/syncthing/config.xml | |
| sed -e "s/<address>127.0.0.1:8384<\/address>/<address>0.0.0.0:$SYNCPORT<\/address>/g" /root/.config/syncthing/config.xml > /root/.config/syncthing/config.xml.tmp && mv /root/.config/syncthing/config.xml.tmp /root/.config/syncthing/config.xml | |
| # Set a symbolic link to connect phpmyadmin and root web directory | |
| ln -s /usr/share/phpmyadmin /var/www/html/${PROJECT,,}/public | |
| # Set Password | |
| VHOST=$(cat <<EOF | |
| AuthType Basic | |
| AuthName "Restricted Files" | |
| AuthUserFile /etc/phpmyadmin/.htpasswd | |
| Require valid-user | |
| EOF | |
| ) | |
| echo "$VHOST" > /usr/share/phpmyadmin/.htaccess | |
| htpasswd -c -b -B -C 14 /etc/phpmyadmin/.htpasswd $USERNAME $HTPASSWORD | |
| # Setup ssl certificates | |
| openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/ssl.key -out /etc/ssl/ssl.crt -subj "/C=US/CN=www.$URL/emailAddress=admin@$URL" | |
| # Replace default configuration | |
| VHOST=$(cat <<EOF | |
| server { | |
| listen 80; | |
| server_name $IP; | |
| return 301 https://$URL; | |
| } | |
| server { | |
| listen 80 default_server; | |
| listen [::]:80 default_server ipv6only=on; | |
| listen 443 ssl; | |
| listen [::]:443 ssl ipv6only=on; | |
| root /var/www/html/${PROJECT,,}/public; | |
| index index.php index.html index.htm; | |
| server_name $URL www.$URL; | |
| ssl_certificate /etc/ssl/ssl.crt; | |
| ssl_certificate_key /etc/ssl/ssl.key; | |
| sendfile on; | |
| error_page 404 /index.php; | |
| location = /favicon.ico { access_log off; log_not_found off; } | |
| location = /robots.txt { access_log off; log_not_found off; } | |
| location /phpmyadmin { | |
| auth_basic "Restricted Files"; | |
| auth_basic_user_file /etc/phpmyadmin/.htpasswd; | |
| } | |
| location / { | |
| try_files \$uri \$uri/ /index.php\$is_args\$args; | |
| } | |
| if (!-d \$request_filename) { | |
| rewrite ^/(.+)/\$ /\$1 permanent; | |
| } | |
| location ~ \.php$ { | |
| fastcgi_split_path_info ^(.+\.php)(/.+)\$; | |
| fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; | |
| fastcgi_index index.php; | |
| include fastcgi_params; | |
| fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; | |
| fastcgi_intercept_errors off; | |
| fastcgi_buffer_size 16k; | |
| fastcgi_buffers 4 16k; | |
| } | |
| location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { | |
| expires 365d; | |
| } | |
| location ~* .*/\..* { | |
| deny all; | |
| } | |
| location ~* /(\.|wp-config.php|readme.html|license.txt|schema.txt|password.txt|passwords.txt) { | |
| deny all; | |
| } | |
| location ~* \.(engine|inc\.php|class\.php|phps|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_ { | |
| deny all; | |
| } | |
| location ~ ~\$ { | |
| access_log off; | |
| log_not_found off; | |
| deny all; | |
| } | |
| } | |
| EOF | |
| ) | |
| echo "$VHOST" > /etc/nginx/sites-available/default | |
| # Optimize Nginx | |
| WORKER_CONNECTIONS=`ulimit -n` | |
| VHOST=$(cat <<EOF | |
| user www-data; | |
| worker_processes auto; | |
| pid /run/nginx.pid; | |
| worker_rlimit_nofile 100000; | |
| events { | |
| use epoll; | |
| worker_connections ${WORKER_CONNECTIONS}; | |
| multi_accept on; | |
| } | |
| http { | |
| ## | |
| # Basic Settings | |
| ## | |
| sendfile on; | |
| tcp_nopush on; | |
| tcp_nodelay on; | |
| keepalive_requests 100000; | |
| keepalive_timeout 45; | |
| reset_timedout_connection on; | |
| client_body_timeout 10; | |
| send_timeout 2; | |
| types_hash_max_size 2048; | |
| open_file_cache max=1000 inactive=20s; | |
| open_file_cache_valid 30s; | |
| open_file_cache_min_uses 5; | |
| open_file_cache_errors off; | |
| server_tokens off; | |
| client_body_buffer_size 16k; | |
| client_header_buffer_size 1k; | |
| client_max_body_size 8m; | |
| large_client_header_buffers 2 4k; | |
| # server_names_hash_bucket_size 64; | |
| # server_name_in_redirect off; | |
| include /etc/nginx/mime.types; | |
| default_type application/octet-stream; | |
| ## | |
| # SSL Settings | |
| ## | |
| ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE | |
| ssl_prefer_server_ciphers on; | |
| ## | |
| # Logging Settings | |
| ## | |
| access_log /var/log/nginx/access.log; | |
| error_log /var/log/nginx/error.log; | |
| ## | |
| # Gzip Settings | |
| ## | |
| gzip on; | |
| gzip_min_length 1024; | |
| gzip_proxied expired no-cache no-store private auth; | |
| gzip_disable "MSIE [1-6]\."; | |
| gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; | |
| gzip_vary on; | |
| # gzip_comp_level 6; | |
| # gzip_buffers 16 8k; | |
| # gzip_http_version 1.1; | |
| ## | |
| # Virtual Host Configs | |
| ## | |
| include /etc/nginx/conf.d/*.conf; | |
| include /etc/nginx/sites-enabled/*; | |
| } | |
| EOF | |
| ) | |
| echo "$VHOST" > /etc/nginx/nginx.conf | |
| # Restart web services | |
| service php7.0-fpm restart | |
| service nginx restart | |
| # Secure mysql installation (mysql_secure_installation) | |
| echo "DELETE FROM mysql.user WHERE User='';" | mysql -uroot -p$PASSWORD | |
| echo "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" | mysql -uroot -p$PASSWORD | |
| echo "DROP DATABASE IF EXISTS test;" | mysql -uroot -p$PASSWORD | |
| echo "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';" | mysql -uroot -p$PASSWORD | |
| echo "FLUSH PRIVILEGES;" | mysql -uroot -p$PASSWORD | |
| # final feedback | |
| echo "Voila!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment