├── .gitignore
├── LICENSE.md
├── README.md
├── configs
├── .env.example
├── controlpanel.conf
├── controlpanel.service
├── controlpanel_ssl.conf
└── www-controlpanel.conf
└── install.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | development
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Ferks
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
ControlPanel-Installer
2 |
3 | 
4 | 
5 |
6 | This is an installation script for [ControlPanel](https://ctrlpanel.gg/)
7 | This script is not associated with the official project.
8 |
9 | Features
10 |
11 | - Automatic installation of the ControlPanel (dependencies, database, cronjob, nginx).
12 | - Automatic configuration of UFW (firewall for Ubuntu/Debian).
13 | - (Optional) automatic configuration of Let's Encrypt.
14 | - (Optional) Automatic panel upgrade to a newer version.
15 |
16 | Support
17 |
18 | For help and support regarding the script itself and **not the official ControlPanel project**, Join our [Support Group](https://discord.gg/buDBbSGJmQ).
19 |
20 | Supported installations
21 |
22 | List of supported installation setups for panel (installations supported by this installation script).
23 |
24 | Systems supported by script
25 |
26 | | Operating System | Version | ✔️ \| ❌ |
27 | | :--- | :--- | :---: |
28 | | Debian | 9 | ✔️ |
29 | | | 10 | ✔️ |
30 | | | 11 | ✔️ |
31 | | Ubuntu | 18 | ✔️ |
32 | | | 20 | ✔️ |
33 | | | 22 | ✔️ |
34 | | CentOS | 7 | ✔️ |
35 | | | 8 | ✔️ |
36 |
37 |
38 | How to use
39 |
40 | Just run the following command as root user.
41 |
42 | ```bash
43 | bash <(curl -s https://raw.githubusercontent.com/Ferks-FK/ControlPanel-Installer/development/install.sh)
44 | ```
45 |
46 | Attention!
47 |
48 | *Do not run the command using sudo.*
49 |
50 | **Example:** ```$ sudo bash <(curl -s...```
51 |
52 | *You must be logged into your system as root to use the command.*
53 |
54 | **Example:** ```# bash <(curl -s...```
55 |
56 |
57 | Development
58 |
59 | This script was created and is being maintained by [Ferks - FK](https://github.com/Ferks-FK).
60 |
61 | Extra informations
62 |
63 | If you have any ideas, or suggestions, feel free to say so in the [Support Group](https://discord.gg/buDBbSGJmQ).
64 |
--------------------------------------------------------------------------------
/configs/.env.example:
--------------------------------------------------------------------------------
1 | ### --- App Settings --- ###
2 | APP_NAME=Controlpanel.gg
3 | APP_ENV=production
4 | APP_KEY=
5 | APP_DEBUG=false
6 | APP_URL=http://localhost
7 | # List with timezones https://www.php.net/manual/en/timezones.php
8 | APP_TIMEZONE=
9 | ### --- App Settings End --- ###
10 |
11 | ### --- DB Settings (required) --- ###
12 | DB_CONNECTION=mysql
13 | DB_HOST=
14 | DB_PORT=
15 | DB_DATABASE=
16 | DB_USERNAME=
17 | DB_PASSWORD=""
18 | ### --- DB Settings End --- ###
19 |
20 |
21 | # Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)
22 | RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
23 | RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
24 |
25 | # Mail Server Settings - (HOST -> SMTP Server)
26 | MAIL_MAILER=smtp
27 | MAIL_HOST=mailhog
28 | MAIL_PORT=1025
29 | MAIL_USERNAME=null
30 | MAIL_PASSWORD=null
31 | MAIL_ENCRYPTION=null
32 | MAIL_FROM_ADDRESS=null
33 | MAIL_FROM_NAME="${APP_NAME}"
34 |
35 |
36 | # Laravel Logging Settings - https://laravel.com/docs/5.7/logging - Not needed to be changed
37 | LOG_CHANNEL=stack
38 | LOG_LEVEL=debug
39 |
40 | # Do not change anything below this line
41 | BROADCAST_DRIVER=log
42 | CACHE_DRIVER=file
43 | QUEUE_CONNECTION=database
44 | SESSION_DRIVER=file
45 | SESSION_LIFETIME=120
46 |
47 | MEMCACHED_HOST=127.0.0.1
48 |
49 | REDIS_HOST=127.0.0.1
50 | REDIS_PASSWORD=null
51 | REDIS_PORT=6379
52 |
53 | AWS_ACCESS_KEY_ID=
54 | AWS_SECRET_ACCESS_KEY=
55 | AWS_DEFAULT_REGION=us-east-1
56 | AWS_BUCKET=
57 |
58 | PUSHER_APP_ID=
59 | PUSHER_APP_KEY=
60 | PUSHER_APP_SECRET=
61 | PUSHER_APP_CLUSTER=mt1
62 |
63 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
64 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
--------------------------------------------------------------------------------
/configs/controlpanel.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | root /var/www/controlpanel/public;
4 | index index.php index.html index.htm index.nginx-debian.html;
5 | server_name ;
6 |
7 | location / {
8 | try_files $uri $uri/ /index.php?$query_string;
9 | }
10 |
11 | location ~ \.php$ {
12 | include snippets/fastcgi-php.conf;
13 | fastcgi_pass unix:;
14 | }
15 |
16 | location ~ /\.ht {
17 | deny all;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/configs/controlpanel.service:
--------------------------------------------------------------------------------
1 | # Controlpanel Queue Worker File
2 | # ----------------------------------
3 |
4 | [Unit]
5 | Description=Controlpanel Queue Worker
6 |
7 | [Service]
8 | # On some systems the user and group might be different.
9 | # Some systems use `apache` or `nginx` as the user and group.
10 | User=
11 | Group=
12 | Restart=always
13 | ExecStart=/usr/bin/php /var/www/controlpanel/artisan queue:work --sleep=3 --tries=3
14 |
15 | [Install]
16 | WantedBy=multi-user.target
--------------------------------------------------------------------------------
/configs/controlpanel_ssl.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name ;
4 | return 301 https://$server_name$request_uri;
5 | }
6 |
7 | server {
8 | listen 443 ssl http2;
9 | server_name ;
10 |
11 | root /var/www/controlpanel/public;
12 | index index.php;
13 |
14 | access_log /var/log/nginx/controlpanel.app-access.log;
15 | error_log /var/log/nginx/controlpanel.app-error.log error;
16 |
17 | # allow larger file uploads and longer script runtimes
18 | client_max_body_size 100m;
19 | client_body_timeout 120s;
20 |
21 | sendfile off;
22 |
23 | # SSL Configuration
24 | ssl_certificate /etc/letsencrypt/live//fullchain.pem;
25 | ssl_certificate_key /etc/letsencrypt/live//privkey.pem;
26 | ssl_session_cache shared:SSL:10m;
27 | ssl_protocols TLSv1.2 TLSv1.3;
28 | ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
29 | ssl_prefer_server_ciphers on;
30 |
31 | add_header X-Content-Type-Options nosniff;
32 | add_header X-XSS-Protection "1; mode=block";
33 | add_header X-Robots-Tag none;
34 | add_header Content-Security-Policy "frame-ancestors 'self'";
35 | add_header X-Frame-Options DENY;
36 | add_header Referrer-Policy same-origin;
37 |
38 | location / {
39 | try_files $uri $uri/ /index.php?$query_string;
40 | }
41 |
42 | location ~ \.php$ {
43 | fastcgi_split_path_info ^(.+\.php)(/.+)$;
44 | fastcgi_pass unix:;
45 | fastcgi_index index.php;
46 | include fastcgi_params;
47 | fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
48 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
49 | fastcgi_param HTTP_PROXY "";
50 | fastcgi_intercept_errors off;
51 | fastcgi_buffer_size 16k;
52 | fastcgi_buffers 4 16k;
53 | fastcgi_connect_timeout 300;
54 | fastcgi_send_timeout 300;
55 | fastcgi_read_timeout 300;
56 | include /etc/nginx/fastcgi_params;
57 | }
58 |
59 | location ~ /\.ht {
60 | deny all;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/configs/www-controlpanel.conf:
--------------------------------------------------------------------------------
1 | [controlpanel]
2 |
3 | user = nginx
4 | group = nginx
5 |
6 | listen = /var/run/php-fpm/controlpanel.sock
7 | listen.owner = nginx
8 | listen.group = nginx
9 | listen.mode = 0750
10 |
11 | pm = ondemand
12 | pm.max_children = 9
13 | pm.process_idle_timeout = 10s
14 | pm.max_requests = 200
15 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # shellcheck source=/dev/null
3 |
4 | set -e
5 |
6 | ########################################################
7 | #
8 | # Pterodactyl-AutoThemes Installation
9 | #
10 | # Created and maintained by Ferks-FK
11 | #
12 | # Protected by MIT License
13 | #
14 | ########################################################
15 |
16 | # Get the latest version before running the script #
17 | get_release() {
18 | curl --silent \
19 | -H "Accept: application/vnd.github.v3+json" \
20 | https://api.github.com/repos/Ferks-FK/ControlPanel-Installer/releases/latest |
21 | grep '"tag_name":' |
22 | sed -E 's/.*"([^"]+)".*/\1/'
23 | }
24 |
25 | # Variables #
26 | SCRIPT_RELEASE="$(get_release)"
27 | SUPPORT_LINK="https://discord.gg/buDBbSGJmQ"
28 | WIKI_LINK="https://github.com/Ferks-FK/ControlPanel-Installer/wiki"
29 | GITHUB_URL="https://raw.githubusercontent.com/Ferks-FK/ControlPanel.gg-Installer/$SCRIPT_RELEASE"
30 | RANDOM_PASSWORD="$(openssl rand -base64 32)"
31 | MYSQL_PASSWORD=false
32 | CONFIGURE_SSL=false
33 | INFORMATIONS="/var/log/ControlPanel-Info"
34 | FQDN=""
35 |
36 | update_variables() {
37 | CLIENT_VERSION="$(grep "'version'" "/var/www/controlpanel/config/app.php" | cut -c18-25 | sed "s/[',]//g")"
38 | LATEST_VERSION="$(curl -s https://raw.githubusercontent.com/Ctrlpanel-gg/panel/main/config/app.php | grep "'version'" | cut -c18-25 | sed "s/[',]//g")"
39 | }
40 |
41 | # Visual Functions #
42 | print_brake() {
43 | for ((n = 0; n < $1; n++)); do
44 | echo -n "#"
45 | done
46 | echo ""
47 | }
48 |
49 | print_warning() {
50 | echo ""
51 | echo -e "* ${YELLOW}WARNING${RESET}: $1"
52 | echo ""
53 | }
54 |
55 | print_error() {
56 | echo ""
57 | echo -e "* ${RED}ERROR${RESET}: $1"
58 | echo ""
59 | }
60 |
61 | print_success() {
62 | echo ""
63 | echo -e "* ${GREEN}SUCCESS${RESET}: $1"
64 | echo ""
65 | }
66 |
67 | print() {
68 | echo ""
69 | echo -e "* ${GREEN}$1${RESET}"
70 | echo ""
71 | }
72 |
73 | hyperlink() {
74 | echo -e "\e]8;;${1}\a${1}\e]8;;\a"
75 | }
76 |
77 | # Colors #
78 | GREEN="\e[0;92m"
79 | YELLOW="\033[1;33m"
80 | RED='\033[0;31m'
81 | RESET="\e[0m"
82 |
83 | EMAIL_RX="^(([A-Za-z0-9]+((\.|\-|\_|\+)?[A-Za-z0-9]?)*[A-Za-z0-9]+)|[A-Za-z0-9]+)@(([A-Za-z0-9]+)+((\.|\-|\_)?([A-Za-z0-9]+)+)*)+\.([A-Za-z]{2,})+$"
84 |
85 | valid_email() {
86 | [[ $1 =~ ${EMAIL_RX} ]]
87 | }
88 |
89 | email_input() {
90 | local __resultvar=$1
91 | local result=''
92 |
93 | while ! valid_email "$result"; do
94 | echo -n "* ${2}"
95 | read -r result
96 |
97 | valid_email "$result" || print_error "${3}"
98 | done
99 |
100 | eval "$__resultvar="'$result'""
101 | }
102 |
103 | password_input() {
104 | local __resultvar=$1
105 | local result=''
106 | local default="$4"
107 |
108 | while [ -z "$result" ]; do
109 | echo -n "* ${2}"
110 | while IFS= read -r -s -n1 char; do
111 | [[ -z $char ]] && {
112 | printf '\n'
113 | break
114 | }
115 | if [[ $char == $'\x7f' ]]; then
116 | if [ -n "$result" ]; then
117 | [[ -n $result ]] && result=${result%?}
118 | printf '\b \b'
119 | fi
120 | else
121 | result+=$char
122 | printf '*'
123 | fi
124 | done
125 | [ -z "$result" ] && [ -n "$default" ] && result="$default"
126 | [ -z "$result" ] && print_error "${3}"
127 | done
128 |
129 | eval "$__resultvar="'$result'""
130 | }
131 |
132 | # OS check #
133 | check_distro() {
134 | if [ -f /etc/os-release ]; then
135 | . /etc/os-release
136 | OS=$(echo "$ID" | awk '{print tolower($0)}')
137 | OS_VER=$VERSION_ID
138 | elif type lsb_release >/dev/null 2>&1; then
139 | OS=$(lsb_release -si | awk '{print tolower($0)}')
140 | OS_VER=$(lsb_release -sr)
141 | elif [ -f /etc/lsb-release ]; then
142 | . /etc/lsb-release
143 | OS=$(echo "$DISTRIB_ID" | awk '{print tolower($0)}')
144 | OS_VER=$DISTRIB_RELEASE
145 | elif [ -f /etc/debian_version ]; then
146 | OS="debian"
147 | OS_VER=$(cat /etc/debian_version)
148 | elif [ -f /etc/SuSe-release ]; then
149 | OS="SuSE"
150 | OS_VER="?"
151 | elif [ -f /etc/redhat-release ]; then
152 | OS="Red Hat/CentOS"
153 | OS_VER="?"
154 | else
155 | OS=$(uname -s)
156 | OS_VER=$(uname -r)
157 | fi
158 |
159 | OS=$(echo "$OS" | awk '{print tolower($0)}')
160 | OS_VER_MAJOR=$(echo "$OS_VER" | cut -d. -f1)
161 | }
162 |
163 | only_upgrade_panel() {
164 | print "Updating your panel, please wait..."
165 |
166 | cd /var/www/controlpanel
167 | php artisan down
168 |
169 | git stash
170 | git pull
171 |
172 | [ "$OS" == "centos" ] && export PATH=/usr/local/bin:$PATH
173 | COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader
174 |
175 | php artisan migrate --seed --force
176 |
177 | php artisan view:clear
178 | php artisan config:clear
179 |
180 | set_permissions
181 |
182 | php artisan queue:restart
183 |
184 | php artisan up
185 |
186 | print "Your panel has been successfully updated to version ${YELLOW}${LATEST_VERSION}${RESET}."
187 | exit 1
188 | }
189 |
190 | enable_services_debian_based() {
191 | systemctl enable mariadb --now
192 | systemctl enable redis-server --now
193 | systemctl enable nginx
194 | }
195 |
196 | enable_services_centos_based() {
197 | systemctl enable mariadb --now
198 | systemctl enable redis --now
199 | systemctl enable nginx
200 | }
201 |
202 | allow_selinux() {
203 | setsebool -P httpd_can_network_connect 1 || true
204 | setsebool -P httpd_execmem 1 || true
205 | setsebool -P httpd_unified 1 || true
206 | }
207 |
208 | centos_php() {
209 | curl -so /etc/php-fpm.d/www-controlpanel.conf "$GITHUB_URL"/configs/www-controlpanel.conf
210 |
211 | systemctl enable php-fpm --now
212 | }
213 |
214 | check_compatibility() {
215 | print "Checking if your system is compatible with the script..."
216 | sleep 2
217 |
218 | case "$OS" in
219 | debian)
220 | PHP_SOCKET="/run/php/php8.1-fpm.sock"
221 | [ "$OS_VER_MAJOR" == "9" ] && SUPPORTED=true
222 | [ "$OS_VER_MAJOR" == "10" ] && SUPPORTED=true
223 | [ "$OS_VER_MAJOR" == "11" ] && SUPPORTED=true
224 | ;;
225 | ubuntu)
226 | PHP_SOCKET="/run/php/php8.1-fpm.sock"
227 | [ "$OS_VER_MAJOR" == "18" ] && SUPPORTED=true
228 | [ "$OS_VER_MAJOR" == "20" ] && SUPPORTED=true
229 | [ "$OS_VER_MAJOR" == "22" ] && SUPPORTED=true
230 | ;;
231 | centos)
232 | PHP_SOCKET="/var/run/php-fpm/controlpanel.sock"
233 | [ "$OS_VER_MAJOR" == "7" ] && SUPPORTED=true
234 | [ "$OS_VER_MAJOR" == "8" ] && SUPPORTED=true
235 | ;;
236 | *)
237 | SUPPORTED=false
238 | ;;
239 | esac
240 |
241 | if [ "$SUPPORTED" == true ]; then
242 | print "$OS $OS_VER is supported!"
243 | else
244 | print_error "$OS $OS_VER is not supported!"
245 | exit 1
246 | fi
247 | }
248 |
249 | ask_ssl() {
250 | echo -ne "* Would you like to configure ssl for your domain? (y/N): "
251 | read -r CONFIGURE_SSL
252 | if [[ "$CONFIGURE_SSL" == [Yy] ]]; then
253 | CONFIGURE_SSL=true
254 | email_input EMAIL "Enter your email address to create the SSL certificate for your domain: " "Email cannot by empty or invalid!"
255 | fi
256 | }
257 |
258 | install_composer() {
259 | print "Installing Composer..."
260 |
261 | curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
262 | }
263 |
264 | download_files() {
265 | print "Downloading Necessary Files..."
266 |
267 | git clone -q https://github.com/Ctrlpanel-gg/panel.git /var/www/controlpanel
268 | rm -rf /var/www/controlpanel/.env.example
269 | curl -so /var/www/controlpanel/.env.example "$GITHUB_URL"/configs/.env.example
270 |
271 | cd /var/www/controlpanel
272 | [ "$OS" == "centos" ] && export PATH=/usr/local/bin:$PATH
273 | COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader
274 | }
275 |
276 | set_permissions() {
277 | print "Setting Necessary Permissions..."
278 |
279 | case "$OS" in
280 | debian | ubuntu)
281 | chown -R www-data:www-data /var/www/controlpanel/
282 | ;;
283 | centos)
284 | chown -R nginx:nginx /var/www/controlpanel/
285 | ;;
286 | esac
287 |
288 | cd /var/www/controlpanel
289 | chmod -R 755 storage/* bootstrap/cache/
290 | }
291 |
292 | configure_environment() {
293 | print "Configuring the base file..."
294 |
295 | sed -i -e "s@@$TIMEZONE@g" /var/www/controlpanel/.env.example
296 | sed -i -e "s@@$DB_HOST@g" /var/www/controlpanel/.env.example
297 | sed -i -e "s@@$DB_PORT@g" /var/www/controlpanel/.env.example
298 | sed -i -e "s@@$DB_NAME@g" /var/www/controlpanel/.env.example
299 | sed -i -e "s@@$DB_USER@g" /var/www/controlpanel/.env.example
300 | sed -i -e "s||$DB_PASS|g" /var/www/controlpanel/.env.example
301 | }
302 |
303 | check_database_info() {
304 | # Check if mysql has a password
305 | if ! mysql -u root -e "SHOW DATABASES;" &>/dev/null; then
306 | MYSQL_PASSWORD=true
307 | print_warning "It looks like your MySQL has a password, please enter it now"
308 | password_input MYSQL_ROOT_PASS "MySQL Password: " "Password cannot by empty!"
309 | if mysql -u root -p"$MYSQL_ROOT_PASS" -e "SHOW DATABASES;" &>/dev/null; then
310 | print "The password is correct, continuing..."
311 | else
312 | print_warning "The password is not correct, please re-enter the password"
313 | check_database_info
314 | fi
315 | fi
316 |
317 | # Checks to see if the chosen user already exists
318 | if [ "$MYSQL_PASSWORD" == true ]; then
319 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "SELECT User FROM mysql.user;" 2>/dev/null >> "$INFORMATIONS/check_user.txt"
320 | else
321 | mysql -u root -e "SELECT User FROM mysql.user;" 2>/dev/null >> "$INFORMATIONS/check_user.txt"
322 | fi
323 | sed -i '1d' "$INFORMATIONS/check_user.txt"
324 | while grep -q "$DB_USER" "$INFORMATIONS/check_user.txt"; do
325 | print_warning "Oops, it looks like user ${GREEN}$DB_USER${RESET} already exists in your MySQL, please use another one."
326 | echo -n "* Database User: "
327 | read -r DB_USER
328 | done
329 | rm -r "$INFORMATIONS/check_user.txt"
330 |
331 | # Check if the database already exists in mysql
332 | if [ "$MYSQL_PASSWORD" == true ]; then
333 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "SHOW DATABASES;" 2>/dev/null >> "$INFORMATIONS/check_db.txt"
334 | else
335 | mysql -u root -e "SHOW DATABASES;" 2>/dev/null >> "$INFORMATIONS/check_db.txt"
336 | fi
337 | sed -i '1d' "$INFORMATIONS/check_db.txt"
338 | while grep -q "$DB_NAME" "$INFORMATIONS/check_db.txt"; do
339 | print_warning "Oops, it looks like the database ${GREEN}$DB_NAME${RESET} already exists in your MySQL, please use another one."
340 | echo -n "* Database Name: "
341 | read -r DB_NAME
342 | done
343 | rm -r "$INFORMATIONS/check_db.txt"
344 | }
345 |
346 | configure_database() {
347 | print "Configuring Database..."
348 |
349 | if [ "$MYSQL_PASSWORD" == true ]; then
350 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "CREATE DATABASE ${DB_NAME};" &>/dev/null
351 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASS}';" &>/dev/null
352 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'${DB_HOST}';" &>/dev/null
353 | mysql -u root -p"$MYSQL_ROOT_PASS" -e "FLUSH PRIVILEGES;" &>/dev/null
354 | else
355 | mysql -u root -e "CREATE DATABASE ${DB_NAME};"
356 | mysql -u root -e "CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASS}';"
357 | mysql -u root -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'${DB_HOST}';"
358 | mysql -u root -e "FLUSH PRIVILEGES;"
359 | fi
360 | }
361 |
362 | configure_webserver() {
363 | print "Configuring Web-Server..."
364 |
365 | if [ "$CONFIGURE_SSL" == true ]; then
366 | WEB_FILE="controlpanel_ssl.conf"
367 | else
368 | WEB_FILE="controlpanel.conf"
369 | fi
370 |
371 | case "$OS" in
372 | debian | ubuntu)
373 | rm -rf /etc/nginx/sites-enabled/default
374 |
375 | curl -so /etc/nginx/sites-available/controlpanel.conf "$GITHUB_URL"/configs/$WEB_FILE
376 |
377 | sed -i -e "s@@$FQDN@g" /etc/nginx/sites-available/controlpanel.conf
378 |
379 | sed -i -e "s@@$PHP_SOCKET@g" /etc/nginx/sites-available/controlpanel.conf
380 |
381 | [ "$OS" == "debian" ] && [ "$OS_VER_MAJOR" == "9" ] && sed -i -e 's/ TLSv1.3//' /etc/nginx/sites-available/controlpanel.conf
382 |
383 | ln -s /etc/nginx/sites-available/controlpanel.conf /etc/nginx/sites-enabled/controlpanel.conf
384 | ;;
385 | centos)
386 | rm -rf /etc/nginx/conf.d/default
387 |
388 | curl -so /etc/nginx/conf.d/controlpanel.conf "$GITHUB_URL"/configs/$WEB_FILE
389 |
390 | sed -i -e "s@@$FQDN@g" /etc/nginx/conf.d/controlpanel.conf
391 |
392 | sed -i -e "s@@$PHP_SOCKET@g" /etc/nginx/conf.d/controlpanel.conf
393 | ;;
394 | esac
395 |
396 | # Kill nginx if it is listening on port 80 before it starts, fixed a port usage bug.
397 | if netstat -tlpn | grep 80 &>/dev/null; then
398 | killall nginx
399 | fi
400 |
401 | if [ "$(systemctl is-active --quiet nginx)" == "active" ]; then
402 | systemctl restart nginx
403 | else
404 | systemctl start nginx
405 | fi
406 | }
407 |
408 | configure_firewall() {
409 | print "Configuring the firewall..."
410 |
411 | case "$OS" in
412 | debian | ubuntu)
413 | apt-get install -qq -y ufw
414 |
415 | ufw allow ssh &>/dev/null
416 | ufw allow http &>/dev/null
417 | ufw allow https &>/dev/null
418 |
419 | ufw --force enable &>/dev/null
420 | ufw --force reload &>/dev/null
421 | ;;
422 | centos)
423 | yum update -y -q
424 |
425 | yum -y -q install firewalld &>/dev/null
426 |
427 | systemctl --now enable firewalld &>/dev/null
428 |
429 | firewall-cmd --add-service=http --permanent -q
430 | firewall-cmd --add-service=https --permanent -q
431 | firewall-cmd --add-service=ssh --permanent -q
432 | firewall-cmd --reload -q
433 | ;;
434 | esac
435 | }
436 |
437 | configure_ssl() {
438 | print "Configuring SSL..."
439 |
440 | FAILED=false
441 |
442 | if [ "$(systemctl is-active --quiet nginx)" == "inactive" ] || [ "$(systemctl is-active --quiet nginx)" == "failed" ]; then
443 | systemctl start nginx
444 | fi
445 |
446 | case "$OS" in
447 | debian | ubuntu)
448 | apt-get update -y -qq && apt-get upgrade -y -qq
449 | apt-get install -y -qq certbot && apt-get install -y -qq python3-certbot-nginx
450 | ;;
451 | centos)
452 | [ "$OS_VER_MAJOR" == "7" ] && yum -y -q install certbot python-certbot-nginx
453 | [ "$OS_VER_MAJOR" == "8" ] && yum -y -q install certbot python3-certbot-nginx
454 | ;;
455 | esac
456 |
457 | certbot certonly --nginx --non-interactive --agree-tos --quiet --no-eff-email --email "$EMAIL" -d "$FQDN" || FAILED=true
458 |
459 | if [ ! -d "/etc/letsencrypt/live/$FQDN/" ] || [ "$FAILED" == true ]; then
460 | if [ "$(systemctl is-active --quiet nginx)" == "active" ]; then
461 | systemctl stop nginx
462 | fi
463 | print_warning "The script failed to generate the SSL certificate automatically, trying alternative command..."
464 | FAILED=false
465 |
466 | certbot certonly --standalone --non-interactive --agree-tos --quiet --no-eff-email --email "$EMAIL" -d "$FQDN" || FAILED=true
467 |
468 | if [ -d "/etc/letsencrypt/live/$FQDN/" ] || [ "$FAILED" == false ]; then
469 | print "The script was able to successfully generate the SSL certificate!"
470 | else
471 | print_warning "The script failed to generate the certificate, try to do it manually."
472 | fi
473 | else
474 | print "The script was able to successfully generate the SSL certificate!"
475 | fi
476 | }
477 |
478 | configure_crontab() {
479 | print "Configuring Crontab"
480 |
481 | crontab -l | {
482 | cat
483 | echo "* * * * * php /var/www/controlpanel/artisan schedule:run >> /dev/null 2>&1"
484 | } | crontab -
485 | }
486 |
487 | configure_service() {
488 | print "Configuring ControlPanel Service..."
489 |
490 | curl -so /etc/systemd/system/controlpanel.service "$GITHUB_URL"/configs/controlpanel.service
491 |
492 | case "$OS" in
493 | debian | ubuntu)
494 | sed -i -e "s@@www-data@g" /etc/systemd/system/controlpanel.service
495 | ;;
496 | centos)
497 | sed -i -e "s@@nginx@g" /etc/systemd/system/controlpanel.service
498 | ;;
499 | esac
500 |
501 | systemctl enable controlpanel.service --now
502 | }
503 |
504 | deps_ubuntu() {
505 | print "Installing dependencies for Ubuntu ${OS_VER}"
506 |
507 | # Add "add-apt-repository" command
508 | apt-get install -y software-properties-common curl apt-transport-https ca-certificates gnupg
509 |
510 | # Add additional repositories for PHP, Redis, and MariaDB
511 | LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php
512 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
513 |
514 | # Update repositories list
515 | apt-get update -y && apt-get upgrade -y
516 |
517 | # Add universe repository if you are on Ubuntu 18.04
518 | [ "$OS_VER_MAJOR" == "18" ] && apt-add-repository universe
519 |
520 | # Install Dependencies
521 | apt-get install -y php8.1 php8.1-{cli,gd,mysql,pdo,mbstring,tokenizer,bcmath,xml,fpm,curl,zip,intl} mariadb-server nginx tar unzip git redis-server psmisc net-tools
522 |
523 | # Enable services
524 | enable_services_debian_based
525 | }
526 |
527 | deps_debian() {
528 | print "Installing dependencies for Debian ${OS_VER}"
529 |
530 | # MariaDB need dirmngr
531 | apt-get install -y dirmngr
532 |
533 | # install PHP 8.0 using sury's repo
534 | apt-get install -y ca-certificates apt-transport-https lsb-release
535 | wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
536 | echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list
537 |
538 | # Add the MariaDB repo
539 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash
540 |
541 | # Update repositories list
542 | apt-get update -y && apt-get upgrade -y
543 |
544 | # Install Dependencies
545 | apt-get install -y php8.1 php8.1-{cli,gd,mysql,pdo,mbstring,tokenizer,bcmath,xml,fpm,curl,zip,intl} mariadb-server nginx tar unzip git redis-server psmisc net-tools
546 |
547 | # Enable services
548 | enable_services_debian_based
549 | }
550 |
551 | deps_centos() {
552 | print "Installing dependencies for CentOS ${OS_VER}"
553 |
554 | if [ "$OS_VER_MAJOR" == "7" ]; then
555 | # SELinux tools
556 | yum install -y policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils setroubleshoot-server setools setools-console mcstrans
557 |
558 | # Install MariaDB
559 | curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash
560 |
561 | # Add remi repo (php8.1)
562 | yum install -y epel-release http://rpms.remirepo.net/enterprise/remi-release-7.rpm
563 | yum install -y yum-utils
564 | yum-config-manager -y --disable remi-php54
565 | yum-config-manager -y --enable remi-php81
566 |
567 | # Install dependencies
568 | yum -y install php php-common php-tokenizer php-curl php-fpm php-cli php-json php-mysqlnd php-mcrypt php-gd php-mbstring php-pdo php-zip php-bcmath php-dom php-opcache php-intl mariadb-server nginx curl tar zip unzip git redis psmisc net-tools
569 | yum update -y
570 | elif [ "$OS_VER_MAJOR" == "8" ]; then
571 | # SELinux tools
572 | yum install -y policycoreutils selinux-policy selinux-policy-targeted setroubleshoot-server setools setools-console mcstrans
573 |
574 | # Add remi repo (php8.1)
575 | yum install -y epel-release http://rpms.remirepo.net/enterprise/remi-release-8.rpm
576 | yum module enable -y php:remi-8.1
577 |
578 | # Install MariaDB
579 | yum install -y mariadb mariadb-server
580 |
581 | # Install dependencies
582 | yum install -y php php-common php-fpm php-cli php-json php-mysqlnd php-gd php-mbstring php-pdo php-zip php-bcmath php-dom php-opcache php-intl mariadb-server nginx curl tar zip unzip git redis psmisc net-tools
583 | yum update -y
584 | fi
585 |
586 | # Enable services
587 | enable_services_centos_based
588 |
589 | # SELinux
590 | allow_selinux
591 | }
592 |
593 | install_controlpanel() {
594 | print "Starting installation, this may take a few minutes, please wait."
595 | sleep 2
596 |
597 | case "$OS" in
598 | debian | ubuntu)
599 | apt-get update -y && apt-get upgrade -y
600 |
601 | [ "$OS" == "ubuntu" ] && deps_ubuntu
602 | [ "$OS" == "debian" ] && deps_debian
603 | ;;
604 | centos)
605 | yum update -y && yum upgrade -y
606 | deps_centos
607 | ;;
608 | esac
609 |
610 | [ "$OS" == "centos" ] && centos_php
611 | install_composer
612 | download_files
613 | set_permissions
614 | configure_environment
615 | check_database_info
616 | configure_database
617 | configure_firewall
618 | configure_crontab
619 | configure_service
620 | [ "$CONFIGURE_SSL" == true ] && configure_ssl
621 | configure_webserver
622 | bye
623 | }
624 |
625 | main() {
626 | # Check if it is already installed and check the version #
627 | if [ -d "/var/www/controlpanel" ]; then
628 | update_variables
629 | if [ "$CLIENT_VERSION" != "$LATEST_VERSION" ]; then
630 | print_warning "You already have the panel installed."
631 | echo -ne "* The script detected that the version of your panel is ${YELLOW}$CLIENT_VERSION${RESET}, the latest version of the panel is ${YELLOW}$LATEST_VERSION${RESET}, would you like to upgrade? (y/N): "
632 | read -r UPGRADE_PANEL
633 | if [[ "$UPGRADE_PANEL" =~ [Yy] ]]; then
634 | check_distro
635 | only_upgrade_panel
636 | else
637 | print "Ok, bye..."
638 | exit 1
639 | fi
640 | else
641 | print_warning "The panel is already installed, aborting..."
642 | exit 1
643 | fi
644 | fi
645 |
646 | # Check if pterodactyl is installed #
647 | if [ ! -d "/var/www/pterodactyl" ]; then
648 | print_warning "An installation of pterodactyl was not found in the directory $YELLOW/var/www/pterodactyl${RESET}"
649 | echo -ne "* Is your pterodactyl panel installed on this machine? (y/N): "
650 | read -r PTERO_DIR
651 | if [[ "$PTERO_DIR" =~ [Yy] ]]; then
652 | echo -e "* ${GREEN}EXAMPLE${RESET}: /var/www/myptero"
653 | echo -ne "* Enter the directory from where your pterodactyl panel is installed: "
654 | read -r PTERO_DIR
655 | if [ -f "$PTERO_DIR/config/app.php" ]; then
656 | print "Pterodactyl was found, continuing..."
657 | else
658 | print_error "Pterodactyl not found, running script again..."
659 | main
660 | fi
661 | fi
662 | fi
663 |
664 | # Check Distro #
665 | check_distro
666 |
667 | # Check if the OS is compatible #
668 | check_compatibility
669 |
670 | # Set FQDN for panel #
671 | while [ -z "$FQDN" ]; do
672 | print_warning "Do not use a domain that is already in use by another application, such as the domain of your pterodactyl."
673 | echo -ne "* Set the Hostname/FQDN for panel (${YELLOW}panel.example.com${RESET}): "
674 | read -r FQDN
675 | [ -z "$FQDN" ] && print_error "FQDN cannot be empty"
676 | done
677 |
678 | # Install the packages to check FQDN and ask about SSL only if FQDN is a string #
679 | if [[ "$FQDN" == [a-zA-Z]* ]]; then
680 | ask_ssl
681 | fi
682 |
683 | # Set host of the database #
684 | echo -ne "* Enter the host of the database (${YELLOW}127.0.0.1${RESET}): "
685 | read -r DB_HOST
686 | [ -z "$DB_HOST" ] && DB_HOST="127.0.0.1"
687 |
688 | # Set port of the database #
689 | echo -ne "* Enter the port of the database (${YELLOW}3306${RESET}): "
690 | read -r DB_PORT
691 | [ -z "$DB_PORT" ] && DB_PORT="3306"
692 |
693 | # Set name of the database #
694 | echo -ne "* Enter the name of the database (${YELLOW}controlpanel${RESET}): "
695 | read -r DB_NAME
696 | [ -z "$DB_NAME" ] && DB_NAME="controlpanel"
697 |
698 | # Set user of the database #
699 | echo -ne "* Enter the username of the database (${YELLOW}controlpaneluser${RESET}): "
700 | read -r DB_USER
701 | [ -z "$DB_USER" ] && DB_USER="controlpaneluser"
702 |
703 | # Set pass of the database #
704 | password_input DB_PASS "Enter the password of the database (Enter for random password): " "Password cannot by empty!" "$RANDOM_PASSWORD"
705 |
706 | # Ask Time-Zone #
707 | echo -e "* List of valid time-zones here: ${YELLOW}$(hyperlink "http://php.net/manual/en/timezones.php")${RESET}"
708 | echo -ne "* Select Time-Zone (${YELLOW}America/New_York${RESET}): "
709 | read -r TIMEZONE
710 | [ -z "$TIMEZONE" ] && TIMEZONE="America/New_York"
711 |
712 | # Summary #
713 | echo
714 | print_brake 75
715 | echo
716 | echo -e "* Hostname/FQDN: $FQDN"
717 | echo -e "* Database Host: $DB_HOST"
718 | echo -e "* Database Port: $DB_PORT"
719 | echo -e "* Database Name: $DB_NAME"
720 | echo -e "* Database User: $DB_USER"
721 | echo -e "* Database Pass: (censored)"
722 | echo -e "* Time-Zone: $TIMEZONE"
723 | echo -e "* Configure SSL: $CONFIGURE_SSL"
724 | echo
725 | print_brake 75
726 | echo
727 |
728 | # Create the logs directory #
729 | mkdir -p $INFORMATIONS
730 |
731 | # Write the information to a log #
732 | {
733 | echo -e "* Hostname/FQDN: $FQDN"
734 | echo -e "* Database Host: $DB_HOST"
735 | echo -e "* Database Port: $DB_PORT"
736 | echo -e "* Database Name: $DB_NAME"
737 | echo -e "* Database User: $DB_USER"
738 | echo -e "* Database Pass: $DB_PASS"
739 | echo ""
740 | echo "* After using this file, delete it immediately!"
741 | } > $INFORMATIONS/install.info
742 |
743 | # Confirm all the choices #
744 | echo -n "* Initial settings complete, do you want to continue to the installation? (y/N): "
745 | read -r CONTINUE_INSTALL
746 | [[ "$CONTINUE_INSTALL" =~ [Yy] ]] && install_controlpanel
747 | [[ "$CONTINUE_INSTALL" == [Nn] ]] && print_error "Installation aborted!" && exit 1
748 | }
749 |
750 | bye() {
751 | echo
752 | print_brake 90
753 | echo
754 | echo -e "${GREEN}* The script has finished the installation process!${RESET}"
755 |
756 | [ "$CONFIGURE_SSL" == true ] && APP_URL="https://$FQDN"
757 | [ "$CONFIGURE_SSL" == false ] && APP_URL="http://$FQDN"
758 |
759 | echo -e "${GREEN}* To complete the configuration of your panel, go to ${YELLOW}$(hyperlink "$APP_URL/install")${RESET}"
760 | echo -e "${GREEN}* Thank you for using this script!"
761 | echo -e "* Wiki: ${YELLOW}$(hyperlink "$WIKI_LINK")${RESET}"
762 | echo -e "${GREEN}* Support Group: ${YELLOW}$(hyperlink "$SUPPORT_LINK")${RESET}"
763 | echo -e "${GREEN}*${RESET} If you have questions about the information that is requested on the installation page\nall the necessary information about it is written in: (${YELLOW}$INFORMATIONS/install.info${RESET})."
764 | echo
765 | print_brake 90
766 | echo
767 | }
768 |
769 | # Exec Script #
770 | main
--------------------------------------------------------------------------------