<!--
  SOC Proposal Rules — Appendix A3: FortiGate VPN
  Production profile rule IDs : 110331-110335

  Severity mapping:
    High → level 12
    Low  → level 5

  Environment: FoodProject uses IPsec site-to-site VPN (IKEv1/IKEv2) and L2TP.
  No SSL-VPN (FortiClient) traffic observed in archives as of 2026-03-20.

  IPsec VPN parent SIDs (built-in Wazuh):
    81622 — Fortigate: VPN user connected (action=tunnel-up, level=information)
    81624 — Fortigate: VPN user disconnected
    81636 — Fortigate: VPN related information (type=event subtype=vpn level=notice)
    81637 — Fortigate: VPN related error   (type=event subtype=vpn level=error)
    81614 — Fortigate: SSL VPN user failed login (ssl-login-fail) — kept for SSL-VPN if enabled

  SSL-VPN rules (110331-110334) are retained but require SSL-VPN to be enabled on FortiGate.
  IPsec/L2TP rules (110335) adapted to match actual tunnel-up events with srccountry != Thailand.
  Field: srccountry (decoded as root-level field, NOT data.srccountry)

  Fix history:
    2026-03-19: Changed if_group=fortigate → if_sid; adapted A3-05 for IPsec tunnel-up
-->
<group name="soc_mvp,appendix_a,a3,vpn,fortigate,">

  <!-- A3-01: VPN authentication success by guest account (SSL-VPN)
       Requires SSL-VPN to be enabled on FortiGate.
       Parent: 81603 (generic base — ssl-login-success is in the raw log) -->
  <rule id="110331" level="12">
    <if_sid>81603</if_sid>
    <match>ssl-login-success</match>
    <match>user="guest"|user=guest</match>
    <description>A3-01 [PROD] SSL-VPN: authentication success by guest account</description>
    <group>soc_prod,a3,vpn_guest,</group>
    <mitre><id>T1078.001</id></mitre>
  </rule>

  <!-- A3-02: SSL-VPN success from different country than last login
       Requires SSL-VPN and FortiGate geo-login tracking -->
  <rule id="110332" level="12">
    <if_sid>81603</if_sid>
    <match>ssl-login-success</match>
    <match>previous_country=</match>
    <description>A3-02 [PROD] SSL-VPN: success from different country than last login</description>
    <group>soc_prod,a3,vpn_geo,</group>
    <mitre><id>T1078</id></mitre>
  </rule>

  <!-- A3-03: SSL-VPN success after prior failures (brute-force indicator)
       Requires SSL-VPN -->
  <rule id="110333" level="12">
    <if_sid>81603</if_sid>
    <match>ssl-login-success</match>
    <match>failed_attempts_before_success=</match>
    <description>A3-03 [PROD] SSL-VPN: success after multiple prior failures (brute-force indicator)</description>
    <group>soc_prod,a3,vpn_bruteforce,</group>
    <mitre><id>T1110.001</id></mitre>
  </rule>

  <!-- A3-04: SSL-VPN multiple account failures from single source IP
       Parent: 81614 (Fortigate: SSL VPN user failed login attempt)
       Requires SSL-VPN -->
  <rule id="110334" level="5">
    <if_sid>81614</if_sid>
    <description>A3-04 [PROD] SSL-VPN: authentication failure (multiple accounts from 1 source)</description>
    <group>soc_prod,a3,vpn_bruteforce,</group>
    <mitre><id>T1110.003</id></mitre>
  </rule>

  <!-- A3-05: VPN tunnel connected from outside Thailand (IPsec + SSL-VPN)
       Parent: 81622 (VPN user connected / action=tunnel-up level=information)
       Real data confirmed: srccountry field present in VPN events
       Fires when IPsec tunnel-up occurs from srccountry != Thailand (Reserved = private/RFC1918)
       Level 13 (> C1 rule 110501 level 12) so this more-specific rule takes priority
       when both conditions are met. Both rules share if_sid=81622. -->
  <rule id="110335" level="13">
    <if_sid>81622</if_sid>
    <field name="srccountry" negate="yes" type="pcre2">^Thailand$|^Reserved$</field>
    <description>A3-05 [PROD] VPN: tunnel connected from outside Thailand</description>
    <group>soc_prod,a3,vpn_geo,</group>
    <mitre><id>T1078</id></mitre>
  </rule>

</group>
