Просмотр исходного кода

Merge branch 'staging/features' into staging/fixes

Jaap Marcus 5 лет назад
Родитель
Сommit
8ad50fc672

+ 4 - 2
CHANGELOG.md

@@ -10,10 +10,12 @@ All notable changes to this project will be documented in this file.
     - `UPGRADE_SEND_EMAIL_LOG` = Sends installation log output to admin email address
 - Upgrade process will now save logs to the `hst_backups` directory.
 - Support for removing backup remote location (#1083)
+- Add support Proftpd TLS Support
+- Add the possibility to assign user "Administrators" rights on login. Replaces "root" login. Notifications are only send towards the "admin" account email
 
-## Bugfixes
+## Buggfixes
+- Removed root login (root / root password )
 - Update apache2.conf replace Include with IncludeOptional (#1072)
-
 - Add ca-certificates, software-properties-common to the dependencies (#1073 + [Forum](https://forum.hestiacp.com/t/hestiscp-fails-on-new-debian-9-vps/1623/8) ) @daniel-eder
 - Fixed issues with database port during backup when port was missing (#1068)
 - Postqresql: forbid the use of upper case (#1084) causing issues with backup / creating database or user

+ 1 - 0
bin/v-add-user

@@ -188,6 +188,7 @@ RKEY='$(generate_password)'
 TWOFA=''
 QRCODE=''
 PHPCLI=''
+ROLE='user'
 SUSPENDED='no'
 SUSPENDED_USERS='0'
 SUSPENDED_WEB='0'

+ 1 - 0
bin/v-change-user-package

@@ -104,6 +104,7 @@ RKEY='$RKEY'
 TWOFA='$TWOFA'
 QRCODE='$QRCODE'
 PHPCLI='$PHPCLI'
+ROLE='$ROLE'
 SUSPENDED='$SUSPENDED'
 SUSPENDED_USERS='$SUSPENDED_USERS'
 SUSPENDED_WEB='$SUSPENDED_WEB'

+ 42 - 0
bin/v-change-user-role

@@ -0,0 +1,42 @@
+#!/bin/bash
+# info: updates user role
+# options: USER ROLE
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Argument definition
+user=$1
+role=$2
+
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/conf/hestia.conf
+
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+# Reading user values
+source $USER_DATA/user.conf
+
+is_format_valid 'user' 'role'
+is_object_valid 'user' 'USER' "$user"
+
+is_object_unsuspended 'user' 'USER' "$user"
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+update_user_value "$user" '$ROLE' "$role"
+
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+
+exit

+ 1 - 1
bin/v-get-user-salt

@@ -61,7 +61,7 @@ check_args '1' "$#" 'USER [IP] [SALT]'
 is_format_valid 'user'
 
 # Checking user
-if [ ! -d "$HESTIA/data/users/$user" ] && [ "$user" != 'root' ]; then
+if [ ! -d "$HESTIA/data/users/$user" ]; then
     echo "Error: password missmatch"
     echo "$date $time $user $ip failed to login" >> $HESTIA/log/auth.log
     exit 9

+ 1 - 0
bin/v-list-user

@@ -45,6 +45,7 @@ json_list() {
         "RKEY": "'$RKEY'",
         "TWOFA": "'$TWOFA'",
         "QRCODE": "'$QRCODE'",
+        "ROLE": "'$ROLE'",
         "SUSPENDED": "'$SUSPENDED'",
         "SUSPENDED_USERS": "'$SUSPENDED_USERS'",
         "SUSPENDED_WEB": "'$SUSPENDED_WEB'",

+ 8 - 0
func/main.sh

@@ -900,6 +900,13 @@ is_object_format_valid() {
     fi
 }
 
+# Role validator 
+is_role_valid (){
+    if ! [[ "$1" =~ ^admin|user$ ]]; then
+        check_result $E_INVALID "invalid $2 format :: $1"
+    fi
+}
+
 # Password validator
 is_password_format_valid() {
     if [ "${#1}" -lt '6' ]; then
@@ -989,6 +996,7 @@ is_format_valid() {
                 quota)          is_int_format_valid "$arg" 'quota' ;;
                 record)         is_common_format_valid "$arg" 'record';;
                 restart)        is_boolean_format_valid "$arg" 'restart' ;;
+                role)           is_role_valid "$arg" 'role' ;;
                 rtype)          is_dns_type_format_valid "$arg" ;;
                 rule)           is_int_format_valid "$arg" "rule id" ;;
                 service)        is_service_format_valid "$arg" "$arg_name" ;;

+ 3 - 0
func/rebuild.sh

@@ -31,6 +31,9 @@ rebuild_user_conf() {
     if [ -z "${PHPCLI+x}" ]; then 
         sed -i "/QRCODE/a PHPCLI=''" $USER_DATA/user.conf 
     fi
+    if [ -z "${ROLE+x}" ]; then 
+        sed -i "/PHPCLI/a ROLE='user'" $USER_DATA/user.conf 
+    fi
     # Run template trigger
     if [ -x "$HESTIA/data/packages/$PACKAGE.sh" ]; then
         $HESTIA/data/packages/$PACKAGE.sh "$user" "$CONTACT" "$NAME"

+ 2 - 0
install/deb/proftpd/proftpd.conf

@@ -4,6 +4,8 @@ ServerAdmin                     root@localhost
 DefaultServer                   on
 DefaultRoot                  ~ !adm
 
+Include /etc/proftpd/tls.conf
+
 <IfModule mod_vroot.c>
     VRootEngine                 on
     VRootAlias                  /etc/security/pam_env.conf etc/security/pam_env.conf

+ 63 - 0
install/deb/proftpd/tls.conf

@@ -0,0 +1,63 @@
+#
+# Proftpd sample configuration for FTPS connections.
+#
+# Note that FTPS impose some limitations in NAT traversing.
+# See http://www.castaglia.org/proftpd/doc/contrib/ProFTPD-mini-HOWTO-TLS.html
+# for more information.
+#
+<IfModule mod_dso.c>
+    # If mod_tls was built as a shared/DSO module, load it
+    LoadModule mod_tls.c
+</IfModule>
+<IfModule mod_tls.c>
+TLSEngine                               on
+TLSLog                                  /var/log/proftpd/tls.log
+# this is an example of protocols, proftp works witl all, but use only the most secure ones like TLSv1.1 and TLSv1.2
+TLSProtocol                             TLSv1.1 TLSv1.2
+#
+# Server SSL certificate. You can generate a self-signed certificate using
+# a command like:
+#
+# openssl req -x509 -newkey rsa:1024 \
+#          -keyout /etc/ssl/private/proftpd.key -out /etc/ssl/certs/proftpd.crt \
+#          -nodes -days 365
+#
+# The proftpd.key file must be readable by root only. The other file can be
+# readable by anyone.
+#
+# chmod 0600 /etc/ssl/private/proftpd.key
+# chmod 0640 /etc/ssl/private/proftpd.key
+#
+TLSRSACertificateFile                   /usr/local/hestia/ssl/certificate.crt
+TLSRSACertificateKeyFile                /usr/local/hestia/ssl/certificate.key
+#
+# CA the server trusts...
+#TLSCACertificateFile                    /etc/ssl/certs/CA.pem
+# ...or avoid CA cert and be verbose
+#TLSOptions                      NoCertRequest EnableDiags
+# ... or the same with relaxed session use for some clients (e.g. FireFtp)
+#TLSOptions                      NoCertRequest EnableDiags NoSessionReuseRequired
+#
+#
+# Per default drop connection if client tries to start a renegotiate
+# This is a fix for CVE-2009-3555 but could break some clients.
+#
+#TLSOptions                                                     AllowClientRenegotiations
+#
+TLSOptions                       NoSessionReuseRequired AllowClientRenegotiations
+# Authenticate clients that want to use FTP over TLS?
+#
+#TLSVerifyClient                         off
+#
+# Are clients required to use FTP over TLS when talking to this server?
+#
+TLSRequired                             off
+#
+# Allow SSL/TLS renegotiations when the client requests them, but
+# do not force the renegotations.  Some clients do not support
+# SSL/TLS renegotiations; when mod_tls forces a renegotiation, these
+# clients will close the data connection, or there will be a timeout
+# on an idle data connection.
+#
+TLSRenegotiate                          required off
+</IfModule>

+ 3 - 1
install/hst-install-debian.sh

@@ -681,7 +681,7 @@ cp /etc/vsftpd.conf $hst_backups/vsftpd > /dev/null 2>&1
 
 # Backup ProFTPD configuration
 systemctl stop proftpd > /dev/null 2>&1
-cp /etc/proftpd.conf $hst_backups/proftpd > /dev/null 2>&1
+cp /etc/proftpd/* $hst_backups/proftpd > /dev/null 2>&1
 
 # Backup Exim configuration
 systemctl stop exim4 > /dev/null 2>&1
@@ -1298,6 +1298,8 @@ if [ "$proftpd" = 'yes' ]; then
     echo "[ * ] Configuring ProFTPD server..."
     echo "127.0.0.1 $servername" >> /etc/hosts
     cp -f $HESTIA_INSTALL_DIR/proftpd/proftpd.conf /etc/proftpd/
+    cp -f $HESTIA_INSTALL_DIR/proftpd/tls.conf /etc/proftpd/
+    
     update-rc.d proftpd defaults > /dev/null 2>&1
     systemctl start proftpd >> $LOG
     check_result $? "proftpd start failed"

+ 2 - 1
install/hst-install-ubuntu.sh

@@ -654,7 +654,7 @@ cp /etc/vsftpd.conf $hst_backups/vsftpd > /dev/null 2>&1
 
 # Backup ProFTPD configuration
 systemctl stop proftpd > /dev/null 2>&1
-cp /etc/proftpd.conf $hst_backups/proftpd > /dev/null 2>&1
+cp /etc/proftpd/* $hst_backups/proftpd > /dev/null 2>&1
 
 # Backup Exim configuration
 systemctl stop exim4 > /dev/null 2>&1
@@ -1339,6 +1339,7 @@ if [ "$proftpd" = 'yes' ]; then
     echo "[ * ] Configuring ProFTPD server..."
     echo "127.0.0.1 $servername" >> /etc/hosts
     cp -f $HESTIA_INSTALL_DIR/proftpd/proftpd.conf /etc/proftpd/
+    cp -f $HESTIA_INSTALL_DIR/proftpd/tls.conf /etc/proftpd/
     update-rc.d proftpd defaults > /dev/null 2>&1
     systemctl start proftpd >> $LOG
     check_result $? "proftpd start failed"

+ 13 - 0
install/upgrade/versions/1.3.0.sh

@@ -29,3 +29,16 @@ if [ "$PROXY_SYSTEM" = "nginx" ]; then
         > /etc/$PROXY_SYSTEM/conf.d/$IP.conf
     done < <(ls $HESTIA/data/ips/)
 fi
+
+if [ "$FTP_SYSTEM" == "proftpd" ]; then
+    if [ -e  /etc/proftpd/proftpd.conf ]; then
+        rm /etc/proftpd/proftpd.conf
+    fi
+    if [ -e  /etc/proftpd/tlss.conf ]; then
+        rm /etc/proftpd/tls.conf
+    fi
+    
+    cp -f $HESTIA_INSTALL_DIR/proftpd/proftpd.conf /etc/proftpd/
+    cp -f $HESTIA_INSTALL_DIR/proftpd/tls.conf /etc/proftpd/
+    
+fi

+ 8 - 0
web/add/user/index.php

@@ -77,6 +77,14 @@ if (!empty($_POST['ok'])) {
         unset($output);
     }
 
+    // Set Role
+    if (empty($_SESSION['error_msg'])) {
+        $v_role = escapeshellarg($_POST['v_role']);
+        exec (HESTIA_CMD."v-change-user-role ".$v_username." ".$v_role, $output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);
+    }
+
     // Send email to the new user
     if ((empty($_SESSION['error_msg'])) && (!empty($v_notify))) {
         $to = $_POST['v_notify'];

+ 9 - 1
web/edit/user/index.php

@@ -38,6 +38,7 @@ $v_shell = $data[$v_username]['SHELL'];
 $v_twofa = $data[$v_username]['TWOFA'];
 $v_qrcode = $data[$v_username]['QRCODE'];
 $v_phpcli = $data[$v_username]['PHPCLI'];
+$v_role = $data[$v_username]['ROLE'];
 $v_ns = $data[$v_username]['NS'];
 $nameservers = explode(",", $v_ns);
 $v_ns1 = $nameservers[0];
@@ -157,7 +158,14 @@ if (!empty($_POST['save'])) {
         check_return_code($return_var,$output);
         unset($output);
     }
-
+    // Change Role (admin only)
+    if (($v_role != $_POST['$v_role']) && ($_SESSION['user'] == 'admin') && (empty($_SESSION['error_msg']))) {
+        $v_role = escapeshellarg($_POST['v_role']);
+        exec (HESTIA_CMD."v-change-user-role ".escapeshellarg($v_username)." ".$v_role, $output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);
+        $v_role = $_POST['v_role'];
+    }
     // Change language
     if (($v_language != $_POST['v_language']) && (empty($_SESSION['error_msg']))) {
         $v_language = escapeshellarg($_POST['v_language']);

+ 1 - 1
web/inc/i18n/en.php

@@ -228,7 +228,7 @@ $LANG['en'] = array(
     'STARTTLS'  => 'STARTTLS',
     'Normal password'  => 'Normal Password',
     'database'  => 'Database',
-    'User'  => 'Username',
+    'User'  => 'User',
     'Host'  => 'Hostname',
     'Charset'  => 'Charset',
     'Min'  => 'Minute',

+ 10 - 7
web/login/index.php

@@ -41,8 +41,9 @@ function authenticate_user(){
         if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
             $v_ip = escapeshellarg($_SERVER['HTTP_CF_CONNECTING_IP']);
         }
-    } 
-     // Get user's salt
+    }    
+    
+    // Get user's salt
     $output = '';
     exec (HESTIA_CMD."v-get-user-salt ".$v_user." ".$v_ip." json" , $output, $return_var);
     $pam = json_decode(implode('', $output), true);
@@ -89,14 +90,10 @@ function authenticate_user(){
                 $error = "<a class=\"error\">".__('Invalid username or password')."</a>";
                 return $error;
             } else {
-
-                // Make root admin user
-                if ($_POST['user'] == 'root') $v_user = 'admin';
-
                 // Get user speciefic parameters
                 exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
                 $data = json_decode(implode('', $output), true);
-
+                unset($output);
                 // Check if 2FA is active
                 if ($data[$_POST['user']]['TWOFA'] != '') {
                    if (empty($_POST['twofa'])){
@@ -113,6 +110,12 @@ function authenticate_user(){
                         }
                    }
                 }
+                
+                if ($data[$_POST['user']]['ROLE'] == 'admin'){
+                    exec (HESTIA_CMD . "v-list-user admin json", $output, $return_var);
+                    $data = json_decode(implode('', $output), true);
+                    unset($output);
+                }
                 // Define session user
                 $_SESSION['user'] = key($data);
                 $v_user = $_SESSION['user'];

+ 13 - 0
web/templates/admin/add_user.html

@@ -131,6 +131,19 @@
                                     </select>
                                 </td>
                             </tr>
+                            <tr>
+                                <td class="vst-text input-label">
+                                    <?php print __('Role');?>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>
+                                    <select class="vst-list" name="v_role">
+                                        <option value="user"><?php print __('User');?>
+                                        <option value="admin" <?php if($v_role == "admin" ){ echo "selected"; } ?> ><?php print __('Administrator');?>
+                                    </select>
+                                </td>
+                            </tr>
                             <tr>
                                 <td class="vst-text input-label">
                                     <?php print __('Language');?>

+ 13 - 0
web/templates/admin/edit_user.html

@@ -138,6 +138,19 @@
                                     </select>
                                 </td>
                             </tr>
+                            <tr>
+                                <td class="vst-text input-label">
+                                    <?php print __('Role');?>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>
+                                    <select class="vst-list" name="v_role">
+                                        <option value="user"><?php print __('User');?>
+                                        <option value="admin" <?php if($v_role == "admin" ){ echo "selected"; } ?> ><?php print __('Administrator');?>
+                                    </select>
+                                </td>
+                            </tr>
                             <tr>
                                 <td class="vst-text input-label">
                                     <?php print __('Language');?>