diff --git a/ansible/files/mui.service.conf b/ansible/files/mui.service.conf index 4e5d34c18..77713e0cc 100644 --- a/ansible/files/mui.service.conf +++ b/ansible/files/mui.service.conf @@ -1,3 +1,5 @@ +pass quick from label "administrators" + # Allow moderator access to mui pass quick inet proto tcp from to (egress:0) port { 80, 443 } pass in quick inet proto tcp to 127.0.0.1 port 8888 rdr-to 10.7.0.200 diff --git a/ansible/files/pf.conf b/ansible/files/pf.conf index 5d57cf5da..4cf8f25e7 100644 --- a/ansible/files/pf.conf +++ b/ansible/files/pf.conf @@ -32,7 +32,6 @@ match on tun from tag OFFENSE_REGISTERED block return quick to { 239.255.255.250, 224/8 } block return log block drop in log quick from -pass quick from label "administrators" pass quick from (self) label "selforigin" include "/etc/service.pf.conf" diff --git a/ansible/files/pui.service.conf b/ansible/files/pui.service.conf index c73dd3c95..fb1fa8ea0 100644 --- a/ansible/files/pui.service.conf +++ b/ansible/files/pui.service.conf @@ -1,12 +1,16 @@ # Allow users to connect to port 80/443 +pass in quick on egress inet proto tcp from {, } to (egress:0) port 8888 rdr-to 127.0.0.1 +pass quick from label "administrators" + pass quick inet proto tcp from to (egress:0) port { 80 , 443 } label "www-moderators" # FOR DT OPERATIONS pass in quick inet proto tcp from to port 80 rdr-to 127.0.0.1 port 8080 label "maintenance" pass in quick inet proto tcp from to port 443 rdr-to 127.0.0.1 port 8443 label "maintenance" +block in quick on egress inet proto tcp from to (egress:0) port 8888 pass in on egress inet proto tcp from to port { 80, 443 } label "www-normal" pass in on egress inet proto tcp to port { 80, 443 } label "www-normal" +pass in quick on egress inet proto tcp to (egress:0) port 8888 rdr-to 127.0.0.1 -pass in quick inet proto tcp from (interconnect:network) to (interconnect:0) port 8888 rdr-to 127.0.0.1 diff --git a/ansible/files/vpn.service.conf b/ansible/files/vpn.service.conf index 9e1977bc4..3fc5c66ce 100644 --- a/ansible/files/vpn.service.conf +++ b/ansible/files/vpn.service.conf @@ -1,3 +1,5 @@ +pass quick from label "administrators" + # Allow moderators to access the service even when in maintenance pass quick on egress inet proto udp from to (egress:0) port 1194 label "OpenVPN" diff --git a/ansible/inventories/servers/group_vars/all.yml b/ansible/inventories/servers/group_vars/all.yml index 70edba665..36688e4ed 100644 --- a/ansible/inventories/servers/group_vars/all.yml +++ b/ansible/inventories/servers/group_vars/all.yml @@ -1,8 +1,16 @@ ## Replace the following with your fork of the repo GITHUB_REPO: git@github.com:echoCTF/echoCTF.RED.git GITHUB_OAUTH_TOKEN: YOUR-GITHUB-TOKEN-FOR-COMPOSER -GITHUB_REPO_BRANCH: THE-DEFAULT-BRANCH +GITHUB_REPO_BRANCH: main # change to your desired branch ## Domain with IN TXT space separated list `IN TXT "1.1.1.1 2.2.2.2" admins_domain: admin.example.com -ansible_python_interpreter: "/usr/local/bin/python3.10" +ansible_python_interpreter: "/usr/local/bin/python3" + +db_ip: "10.7.0.253" +pui_ip: "10.7.0.200" +mui_ip: "10.7.0.201" +vpn_ip: "10.7.0.254" +interconnect_interface: "vio1" +pui_ext_ip: "1.2.3.4" +mui_ext_ip: "1.2.3.4" diff --git a/ansible/inventories/servers/group_vars/vpn.yml b/ansible/inventories/servers/group_vars/vpn.yml index 3af173eff..4eba79fa7 100644 --- a/ansible/inventories/servers/group_vars/vpn.yml +++ b/ansible/inventories/servers/group_vars/vpn.yml @@ -1,17 +1,17 @@ REPO: /root/sources vpngw: "vpngw.example.red" -egress_if: "em0" -targets_if: "em1" -targets_if_ipv4: "10.0.160.254" -targets_subnet: "10.0.160.0" -targets_netmask: "255.255.255.0" +egress_if: "vio0" +targets_if: "vio1" +targets_if_ipv4: "10.0.0.254" +targets_subnet: "10.0.0.0" +targets_netmask: "255.255.0.0" echoCTF_VPN_mgmt_passwd: "openvpn" offense_network: "10.10.0.0/16" -db_host: "172.24.0.253" +db_host: "10.7.0.253" db_name: "echoCTF" db_user: "vpnuser" db_pass: "vpnuserpass" -interconnect_interface: em2 +interconnect_interface: vio2 interconnect_interface_ip: 10.7.0.254 ## Memcache port memc_port: 11211 diff --git a/ansible/inventories/servers/host_vars/mui.yml b/ansible/inventories/servers/host_vars/mui.yml index ba515b011..8a367686f 100644 --- a/ansible/inventories/servers/host_vars/mui.yml +++ b/ansible/inventories/servers/host_vars/mui.yml @@ -1,9 +1,18 @@ hostname: mui.mydomain -moderator_domain: mui.mydomain +domain_name: mui.mydomain backups: - { tgz: "/altroot/root.tgz", src: '/root' } - { tgz: "/altroot/etc.tgz", src: '/etc' } - { tgz: "/altroot/varcron.tgz", src: '/var/cron' } - { tgz: "/altroot/home.tgz", src: '/home' } -REPO: "/home/moderatorUI/{{moderator_domain}}" \ No newline at end of file +REPO: "/home/moderatorUI/{{domain_name}}" +APP_USER: moderatorUI +APP_SERVICES: + - php84_fpm + - moderator +PRESERVE_PATHS: + - backend/web/identificationFiles/ + - backend/config/db.php + - backend/config/cache.php + - backend/config/validationKey.php diff --git a/ansible/inventories/servers/host_vars/pui.yml b/ansible/inventories/servers/host_vars/pui.yml index f1cf7ca38..7d3f5f876 100644 --- a/ansible/inventories/servers/host_vars/pui.yml +++ b/ansible/inventories/servers/host_vars/pui.yml @@ -1,5 +1,5 @@ hostname: pui.mydomain -offense_domain: pui.mydomain +domain_name: pui.mydomain backups: - { tgz: "/altroot/root.tgz", src: '/root' } - { tgz: "/altroot/etc.tgz", src: '/etc' } @@ -7,4 +7,16 @@ backups: - { tgz: "/altroot/var.tgz", src: '/var' } - { tgz: "/altroot/home.tgz", src: '/home' } -REPO: "/home/participantUI/{{offense_domain}}" \ No newline at end of file +REPO: "/home/participantUI/{{domain_name}}" +APP_USER: participantUI +APP_SERVICES: + - php84_fpm + - participant +PRESERVE_PATHS: + - frontend/web/images/avatars/ + - frontend/web/images/targets/ + - frontend/web/identificationFiles/ + - frontend/config/db.php + - frontend/config/cache.php + - frontend/config/validationKey.php + - frontend/config/routes.php diff --git a/ansible/runonce/db.yml b/ansible/runonce/db.yml index 1ccc80b65..3409ab90d 100755 --- a/ansible/runonce/db.yml +++ b/ansible/runonce/db.yml @@ -453,19 +453,6 @@ - { cmd: "touch /etc/match-findings-pf.conf", creates: "/etc/match-findings-pf.conf" } - { cmd: "install -m 0500 /etc/examples/rc.local /etc/rc.local", creates: "/etc/rc.local" } - - name: Execute fw_update - command: fw_update -a - - - name: Execute syspatch - command: syspatch - failed_when: result.rc not in [0,2] - register: result - - - name: Re-Execute syspatch in case it updated it self on the previous run - command: syspatch - failed_when: result.rc not in [0,2] - register: result - - name: Update crontab PATH variable cron: user: root @@ -486,5 +473,18 @@ - { name: "events checker", minute: "*/1", job: "-ns /usr/local/sbin/mysql-events-checker" } - { name: "daily database backups", minute: "0",hour: "23", job: "-ns /usr/local/sbin/database_backup" } + - name: Execute fw_update + command: fw_update -a + + - name: Execute syspatch + command: syspatch + failed_when: result.rc not in [0,2] + register: result + + - name: Re-Execute syspatch in case it updated it self on the previous run + command: syspatch + failed_when: result.rc not in [0,2] + register: result + - name: display post install message debug: msg="Make sure you've added your IP to the administrators.conf and reboot the system for the changes to take effect" diff --git a/ansible/runonce/mui.yml b/ansible/runonce/mui.yml index 22644df18..b3c247965 100755 --- a/ansible/runonce/mui.yml +++ b/ansible/runonce/mui.yml @@ -3,7 +3,7 @@ - hosts: all gather_facts: false vars_prompt: - - name: "myname" + - name: "hostname" prompt: "1/7. System hostname?" default: "mui.example.local" private: no @@ -41,7 +41,7 @@ PHP_MINOR: "6" AUTOCONF: "2.69" AUTOMAKE: "1.16" - ICU_MAJOR: 76 + ICU_MAJOR: 77 ICU_MINOR: 1 sysctl: kern.bufcachepercent: 30 @@ -97,9 +97,9 @@ - "php-intl%{{versions.PHP}}" - "php-pdo_mysql%{{versions.PHP}}" - "php-zip%{{versions.PHP}}" - - "php-bcmath%{{versions.PHP}}" + #- "php-bcmath%{{versions.PHP}}" - "php-gmp%{{versions.PHP}}" - - "php-mcrypt%{{versions.PHP}}" + #- "php-mcrypt%{{versions.PHP}}" - "php-tidy%{{versions.PHP}}" - py3-pip - py3-requests @@ -120,16 +120,16 @@ - name: Set hostname hostname: - name: "{{myname}}" + name: "{{hostname}}" - name: Make hostname permanent (/etc/myname) copy: - content: "{{ myname }}\n" + content: "{{ hostname }}\n" dest: /etc/myname - name: Create fresh /etc/hosts copy: - content: "127.0.0.1 localhost\n{{db_ip}} db\n{{mui_ext_ip}} {{ myname.split('.')[0] | lower }} {{ myname }}\n" + content: "127.0.0.1 localhost\n{{db_ip}} db\n{{mui_ext_ip}} {{ hostname.split('.')[0] | lower }} {{ hostname }}\n" dest: /etc/hosts - name: Configure interconnect interface @@ -271,8 +271,8 @@ src: "{{item.src}}" dest: "{{item.dest}}" with_items: - - { src: '{{playbook_dir}}/../templates/httpd.conf.j2', dest: '/etc/httpd.conf', domain: '{{myname}}' } - - { src: '{{playbook_dir}}/../templates/acme-client.conf.j2', dest: '/etc/acme-client.conf', domain: '{{myname}}', challenge_dir: "/home/moderatortUI/acme/.well-known/acme-challenge/" } + - { src: '{{playbook_dir}}/../templates/httpd.conf.j2', dest: '/etc/httpd.conf', domain: '{{hostname}}' } + - { src: '{{playbook_dir}}/../templates/acme-client.conf.j2', dest: '/etc/acme-client.conf', domain: '{{hostname}}', challenge_dir: "/home/moderatortUI/acme/.well-known/acme-challenge/" } - name: Generate pf tables files command: "{{item.cmd}}" diff --git a/ansible/runonce/pui.yml b/ansible/runonce/pui.yml index bf4d29c87..9a1ed2bf4 100755 --- a/ansible/runonce/pui.yml +++ b/ansible/runonce/pui.yml @@ -4,7 +4,7 @@ hosts: all gather_facts: false vars_prompt: - - name: "myname" + - name: "hostname" prompt: "1/7. System hostname?" default: "pui.example.local" private: no @@ -54,7 +54,7 @@ PHP_MINOR: "6" AUTOCONF: "2.69" AUTOMAKE: "1.16" - ICU_MAJOR: 76 + ICU_MAJOR: 77 ICU_MINOR: 1 sysctl: kern.bufcachepercent: 30 @@ -102,9 +102,9 @@ - "php-intl%{{versions.PHP}}" - "php-pdo_mysql%{{versions.PHP}}" - "php-zip%{{versions.PHP}}" - - "php-bcmath%{{versions.PHP}}" + #- "php-bcmath%{{versions.PHP}}" - "php-gmp%{{versions.PHP}}" - - "php-mcrypt%{{versions.PHP}}" + #- "php-mcrypt%{{versions.PHP}}" - certbot - py3-pip - py3-requests @@ -125,16 +125,16 @@ - name: Set hostname hostname: - name: "{{myname}}" + name: "{{hostname}}" - name: Make hostname permanent (/etc/myname) copy: - content: "{{ myname }}\n" + content: "{{ hostname }}\n" dest: /etc/myname - name: Create fresh /etc/hosts copy: - content: "127.0.0.1 localhost\n{{db_ip}} db\n{{pui_ext_ip}} {{ myname.split('.')[0] | lower }} {{ myname }}\n" + content: "127.0.0.1 localhost\n{{db_ip}} db\n{{pui_ext_ip}} {{ hostname.split('.')[0] | lower }} {{ hostname }}\n" dest: /etc/hosts - name: Configure interconnect interface @@ -488,10 +488,12 @@ command: "{{item}}" with_items: - mkdir -p /home/participantUI/{{domain_name}}/frontend/web/assets + - mkdir -p /home/participantUI/{{domain_name}}/frontend/web/identificationFiles - mkdir -p /home/participantUI/{{domain_name}}/frontend/web/images/avatars/team - mkdir -p /var/log/cron - chown -R participantUI /home/participantUI/{{domain_name}}/frontend/web/assets - chown -R participantUI /home/participantUI/{{domain_name}}/frontend/web/images/avatars/ + - chown -R participantUI /home/participantUI/{{domain_name}}/frontend/web/identificationFiles - ln -sf /home/participantUI/{{domain_name}}/frontend/yii /usr/local/bin/frontend - name: configure participant rc.d @@ -612,7 +614,7 @@ - name: Grab wsserver get_url: - url: "https://github.com/echoCTF/ws-server/releases/download/v1.0.0/wsserver-openbsd-amd64.zip" + url: "https://github.com/echoCTF/ws-server/releases/latest/download/wsserver-openbsd-amd64.zip" dest: /tmp/wsserver.zip - name: Extract wsserver @@ -627,7 +629,7 @@ content: | [program:wsserver] user = participantUI - command = /usr/local/bin/wsserver -addr "127.0.0.1:8888" -db mysql -dsn "participantUI:participantUI@{{db_ip}}/echoCTF" -max-queued 20 + command = /usr/local/bin/wsserver-openbsd-amd64 -addr "127.0.0.1:8888" -db mysql -dsn "participantUI:participantUI@tcp({{db_ip}})/echoCTF" -max-queued 20 stdout_logfile=/var/log/wsserver.log stdout_logfile_maxbytes=0 redirect_stderr=true diff --git a/ansible/runonce/vpngw.yml b/ansible/runonce/vpngw.yml index a3e252118..495bcef33 100755 --- a/ansible/runonce/vpngw.yml +++ b/ansible/runonce/vpngw.yml @@ -568,7 +568,7 @@ creates: "{{item.creates|default(omit)}}" chdir: "{{item.chdir|default(omit)}}" with_items: - - { cmd: "ln -s {{APP_DIR}}/backend/yii /usr/local/bin/backend"} + - { cmd: "ln -sf {{APP_DIR}}/backend/yii /usr/local/bin/backend"} - { cmd: "openssl dhparam -out /etc/openvpn/dh.pem 2048", creates: "/etc/openvpn/dh.pem" } - { cmd: "openvpn --genkey secret /etc/openvpn/private/vpn-ta.key", creates: "/etc/openvpn/private/vpn-ta.key" } - { cmd: "{{APP_DIR}}/backend/yii migrate --interactive=0" } diff --git a/backend/modules/settings/views/sysconfig/configure.php b/backend/modules/settings/views/sysconfig/configure.php index d498ee836..435fdcf7e 100644 --- a/backend/modules/settings/views/sysconfig/configure.php +++ b/backend/modules/settings/views/sysconfig/configure.php @@ -48,6 +48,7 @@
field($model, 'player_monthly_rankings')->checkbox()->hint('Show monthly leaderboards by points?') ?>
field($model, 'country_rankings')->checkbox()->hint('Show country based leaderboards?') ?>
field($model, 'team_only_leaderboards')->checkbox()->hint('Show only team based leaderboards?') ?>
+
field($model, 'writeup_rankings')->checkbox()->hint('Enable writeup rankings?') ?>

@@ -69,7 +70,6 @@
field($model, 'target_hide_inactive')->checkbox()->hint('Hide inactive targets from listings?') ?>
field($model, 'target_guest_view_deny')->checkbox()->hint('Hide targets from guests?') ?>
field($model, 'network_view_guest')->checkbox()->hint('Allow guests to view networks?') ?>
-
field($model, 'writeup_rankings')->checkbox()->hint('Enable writeup ratings?') ?>
field($model, 'stream_player_target_help')->checkbox()->hint('Log writeup activations on activity stream?') ?>
field($model, 'log_failed_claims')->checkbox()->hint('Log failed treasure claims?') ?>
field($model, 'force_findings_to_claim')->checkbox()->hint('Force findings before claim?') ?>
diff --git a/contrib/sample-migrations/m000000_000003_add_extra_docker_servers.php b/contrib/sample-migrations/m000000_000003_add_extra_docker_servers.php index c2233283a..f5addeab9 100644 --- a/contrib/sample-migrations/m000000_000003_add_extra_docker_servers.php +++ b/contrib/sample-migrations/m000000_000003_add_extra_docker_servers.php @@ -10,11 +10,8 @@ class m000000_000003_add_extra_docker_servers extends Migration public $minsrv = 1; public $maxsrv = 4; public $server = [ - 'name' => 'docker%d', - 'ip' => '%d', 'network' => 'AAnet', 'service' => 'docker', - 'connstr' => 'tcp://10.0.0.%d:2376', 'provider_id' => 'vultr' ]; /** @@ -23,7 +20,7 @@ class m000000_000003_add_extra_docker_servers extends Migration public function safeUp() { for ($i = $this->minsrv; $i <= $this->maxsrv; $i++) { - $this->server['name'] = sprintf("docker%0d", $i); + $this->server['name'] = sprintf("docker%02d", $i); $this->server['ip'] = ip2long('10.0.0.' . $i); $this->server['connstr'] = sprintf("tcp://10.0.0.%d:2376", $i); $this->upsert('server', $this->server); @@ -36,7 +33,7 @@ public function safeUp() public function safeDown() { for ($i = $this->minsrv; $i <= $this->maxsrv; $i++) { - $this->server['name'] = sprintf("docker%0d", $i); + $this->server['name'] = sprintf("docker%02d", $i); $this->server['ip'] = ip2long('10.0.0.' . $i); $this->server['connstr'] = sprintf("tcp://10.0.0.%d:2376", $i); $this->delete('server', $this->server); diff --git a/frontend/components/PlayerEvents.php b/frontend/components/PlayerEvents.php index aba494447..60a27c12e 100644 --- a/frontend/components/PlayerEvents.php +++ b/frontend/components/PlayerEvents.php @@ -20,11 +20,7 @@ public static function giveInitialHint($event) public static function sendInitialNotification($event) { - $n=new \app\models\Notification; - $n->player_id=$event->sender->id; - $n->archived=0; - $n->body=$n->title=\Yii::t('app',"Hi there, don't forget to read the Instructions"); - $n->save(); + $event->sender->notify('info',\Yii::t('app',"Hi there, don't forget to read the Instructions"),\Yii::t('app',"Hi there, don't forget to read the Instructions")); } public static function addStream($event) diff --git a/frontend/controllers/LegalController.php b/frontend/controllers/LegalController.php index 30d102379..25cd74d85 100644 --- a/frontend/controllers/LegalController.php +++ b/frontend/controllers/LegalController.php @@ -1,45 +1,50 @@ [ - 'class' => AccessControl::class, - 'only' => ['privacy-policy','terms-and-conditions'], - 'rules' => [ - 'disabledRoute'=>[ - 'actions' => ['privacy-policy','terms-and-conditions'], - ], - [ - 'actions' => ['privacy-policy','terms-and-conditions'], - 'allow' => true, - ], - ], - ], - ]); - } + public function behaviors() + { + $parent = parent::behaviors(); + unset($parent['access']['rules']['teamsAccess']); + unset($parent['access']['rules']['eventStartEnd']); + unset($parent['access']['rules']['eventStart']); - public function actionPrivacyPolicy() - { - $content=\app\modelscli\Pages::findOne(2); - if ($content===null) - return $this->redirect('/'); - return $this->render('privacy-policy',['content'=>$content]); - } + return ArrayHelper::merge($parent, [ + 'access' => [ + 'class' => AccessControl::class, + 'only' => ['privacy-policy', 'terms-and-conditions'], + 'rules' => [ + 'disabledRoute' => [ + 'actions' => ['privacy-policy', 'terms-and-conditions'], + ], + [ + 'actions' => ['privacy-policy', 'terms-and-conditions'], + 'allow' => true, + ], + ], + ], + ]); + } - public function actionTermsAndConditions() - { - $content=\app\modelscli\Pages::findOne(1); - if ($content===null) - return $this->redirect('/'); - return $this->render('terms-and-conditions',['content'=>$content]); - } + public function actionPrivacyPolicy() + { + $content = \app\modelscli\Pages::findOne(['slug'=>'privacy-policy']); + if ($content === null) + return $this->redirect('/'); + return $this->render('privacy-policy', ['content' => $content]); + } + public function actionTermsAndConditions() + { + $content = \app\modelscli\Pages::findOne(['slug'=>'terms-and-conditions']); + if ($content === null) + return $this->redirect('/'); + return $this->render('terms-and-conditions', ['content' => $content]); + } } diff --git a/frontend/themes/material/profile/_card.php b/frontend/themes/material/profile/_card.php index fc0cd774c..9670ae83b 100644 --- a/frontend/themes/material/profile/_card.php +++ b/frontend/themes/material/profile/_card.php @@ -82,7 +82,9 @@ +sys->team_only_leaderboards!==true):?> + diff --git a/frontend/themes/material/profile/index.php b/frontend/themes/material/profile/index.php index 0d7239f78..41f5e3872 100644 --- a/frontend/themes/material/profile/index.php +++ b/frontend/themes/material/profile/index.php @@ -74,6 +74,7 @@ render('_profile_tabs',['profile'=>$profile,'game'=>$game,'headshots'=>$headshots]);?> +sys->team_only_leaderboards!==true):?>
+
'stream-listing', 'enablePushState'=>false, 'linkSelector'=>'#stream-pager a', 'formSelector'=>false]); diff --git a/frontend/themes/material/site/signup.php b/frontend/themes/material/site/signup.php index bf687c7dd..8acf85afe 100644 --- a/frontend/themes/material/site/signup.php +++ b/frontend/themes/material/site/signup.php @@ -30,7 +30,7 @@ field($model, 'affiliation')->textInput()->label("Affiliation") ?> - field($model, 'identificationFile')->fileInput()->hint('Attach proof of identification (accepted formats: pdf,png,jpeg) format')->label('Identification', ['class' => 'btn btn-raised btn-round btn-info btn-file']) ?> + field($model, 'identificationFile')->fileInput()->hint('Attach proof of identification (accepted formats: pdf, png, jpeg)')->label('Identification', ['class' => 'btn btn-raised btn-round btn-info btn-file']) ?> field($model, 'username')->textInput(['autofocus' => true]) ?>