├── .gitignore ├── README.md ├── ansible.cfg ├── get_facts.yml ├── group_vars └── svpnprod │ ├── policy_prefix_list.yml │ ├── policy_statement.yml │ ├── routing_options.yml │ └── system_accounts.yml ├── host_vars ├── svpn-aws-1 │ ├── bgp_config.yml │ ├── bgp_neighbors_ebgp.yml │ ├── ipsec.yml │ └── svpn-aws-1.yml └── svpn-aws-2 │ ├── bgp_config.yml │ ├── bgp_neighbors_ebgp.yml │ ├── ipsec.yml │ └── svpn-aws-2.yml ├── inventory.ini ├── library ├── check_bgp_status └── check_bgp_status.py ├── linter.sh ├── napalm_example.py ├── napalm_example_set.py ├── playbook_check.yml ├── playbook_napalm.yml ├── playbook_napalm_commit.yml ├── playbook_test.yml ├── requirements.txt └── roles ├── bgp ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── bgp.j2 │ └── include │ ├── frr_bgp.j2 │ └── quagga_bgp.j2 ├── firewall ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── firewall.j2 │ └── include │ └── firewall_rules.j2 ├── interfaces ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── include │ ├── interfaces.j2 │ └── interfaces_vti.j2 │ └── interfaces.j2 ├── ipsec ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── include │ ├── ipsec_peers.j2 │ └── ipsec_settings.j2 │ └── ipsec.j2 ├── nat ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── include │ ├── nat_destination_rules.j2 │ └── nat_source_rules.j2 │ └── nat.j2 ├── policy ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── include │ ├── policy_mss.j2 │ ├── policy_prefix_list.j2 │ └── policy_statement.j2 │ └── policy.j2 ├── protocols ├── README.md ├── tasks │ └── main.yml └── templates │ └── vyos │ ├── include │ └── protocols_static.j2 │ └── protocols.j2 └── system ├── README.md ├── tasks └── main.yml └── templates └── vyos ├── include ├── system_accounts.j2 ├── system_banner.j2 ├── system_base.j2 ├── system_dhcp_relay.j2 ├── system_dns.j2 ├── system_interfaces.j2 ├── system_ntp.j2 ├── system_snmp.j2 ├── system_ssh.j2 └── system_syslog.j2 ├── rc.local.j2 └── system.j2 /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/ansible,visualstudio 3 | # Edit at https://www.gitignore.io/?templates=ansible,visualstudio 4 | 5 | ### Ansible ### 6 | *.retry 7 | 8 | ### VisualStudio ### 9 | ## Ignore Visual Studio temporary files, build results, and 10 | ## files generated by popular Visual Studio add-ons. 11 | ## 12 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 13 | 14 | # User-specific files 15 | *.rsuser 16 | *.suo 17 | *.user 18 | *.userosscache 19 | *.sln.docstates 20 | 21 | # User-specific files (MonoDevelop/Xamarin Studio) 22 | *.userprefs 23 | 24 | # Build results 25 | [Dd]ebug/ 26 | [Dd]ebugPublic/ 27 | [Rr]elease/ 28 | [Rr]eleases/ 29 | x64/ 30 | x86/ 31 | [Aa][Rr][Mm]/ 32 | [Aa][Rr][Mm]64/ 33 | bld/ 34 | [Bb]in/ 35 | [Oo]bj/ 36 | [Ll]og/ 37 | 38 | # Visual Studio 2015/2017 cache/options directory 39 | .vs/ 40 | # Uncomment if you have tasks that create the project's static files in wwwroot 41 | #wwwroot/ 42 | 43 | # Visual Studio 2017 auto generated files 44 | Generated\ Files/ 45 | 46 | # MSTest test Results 47 | [Tt]est[Rr]esult*/ 48 | [Bb]uild[Ll]og.* 49 | 50 | # NUNIT 51 | *.VisualState.xml 52 | TestResult.xml 53 | 54 | # Build Results of an ATL Project 55 | [Dd]ebugPS/ 56 | [Rr]eleasePS/ 57 | dlldata.c 58 | 59 | # Benchmark Results 60 | BenchmarkDotNet.Artifacts/ 61 | 62 | # .NET Core 63 | project.lock.json 64 | project.fragment.lock.json 65 | artifacts/ 66 | 67 | # StyleCop 68 | StyleCopReport.xml 69 | 70 | # Files built by Visual Studio 71 | *_i.c 72 | *_p.c 73 | *_h.h 74 | *.ilk 75 | *.meta 76 | *.obj 77 | *.iobj 78 | *.pch 79 | *.pdb 80 | *.ipdb 81 | *.pgc 82 | *.pgd 83 | *.rsp 84 | *.sbr 85 | *.tlb 86 | *.tli 87 | *.tlh 88 | *.tmp 89 | *.tmp_proj 90 | *_wpftmp.csproj 91 | *.log 92 | *.vspscc 93 | *.vssscc 94 | .builds 95 | *.pidb 96 | *.svclog 97 | *.scc 98 | 99 | # Chutzpah Test files 100 | _Chutzpah* 101 | 102 | # Visual C++ cache files 103 | ipch/ 104 | *.aps 105 | *.ncb 106 | *.opendb 107 | *.opensdf 108 | *.sdf 109 | *.cachefile 110 | *.VC.db 111 | *.VC.VC.opendb 112 | 113 | # Visual Studio profiler 114 | *.psess 115 | *.vsp 116 | *.vspx 117 | *.sap 118 | 119 | # Visual Studio Trace Files 120 | *.e2e 121 | 122 | # TFS 2012 Local Workspace 123 | $tf/ 124 | 125 | # Guidance Automation Toolkit 126 | *.gpState 127 | 128 | # ReSharper is a .NET coding add-in 129 | _ReSharper*/ 130 | *.[Rr]e[Ss]harper 131 | *.DotSettings.user 132 | 133 | # JustCode is a .NET coding add-in 134 | .JustCode 135 | 136 | # TeamCity is a build add-in 137 | _TeamCity* 138 | 139 | # DotCover is a Code Coverage Tool 140 | *.dotCover 141 | 142 | # AxoCover is a Code Coverage Tool 143 | .axoCover/* 144 | !.axoCover/settings.json 145 | 146 | # Visual Studio code coverage results 147 | *.coverage 148 | *.coveragexml 149 | 150 | # NCrunch 151 | _NCrunch_* 152 | .*crunch*.local.xml 153 | nCrunchTemp_* 154 | 155 | # MightyMoose 156 | *.mm.* 157 | AutoTest.Net/ 158 | 159 | # Web workbench (sass) 160 | .sass-cache/ 161 | 162 | # Installshield output folder 163 | [Ee]xpress/ 164 | 165 | # DocProject is a documentation generator add-in 166 | DocProject/buildhelp/ 167 | DocProject/Help/*.HxT 168 | DocProject/Help/*.HxC 169 | DocProject/Help/*.hhc 170 | DocProject/Help/*.hhk 171 | DocProject/Help/*.hhp 172 | DocProject/Help/Html2 173 | DocProject/Help/html 174 | 175 | # Click-Once directory 176 | publish/ 177 | 178 | # Publish Web Output 179 | *.[Pp]ublish.xml 180 | *.azurePubxml 181 | # Note: Comment the next line if you want to checkin your web deploy settings, 182 | # but database connection strings (with potential passwords) will be unencrypted 183 | *.pubxml 184 | *.publishproj 185 | 186 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 187 | # checkin your Azure Web App publish settings, but sensitive information contained 188 | # in these scripts will be unencrypted 189 | PublishScripts/ 190 | 191 | # NuGet Packages 192 | *.nupkg 193 | # The packages folder can be ignored because of Package Restore 194 | **/[Pp]ackages/* 195 | # except build/, which is used as an MSBuild target. 196 | !**/[Pp]ackages/build/ 197 | # Uncomment if necessary however generally it will be regenerated when needed 198 | #!**/[Pp]ackages/repositories.config 199 | # NuGet v3's project.json files produces more ignorable files 200 | *.nuget.props 201 | *.nuget.targets 202 | 203 | # Microsoft Azure Build Output 204 | csx/ 205 | *.build.csdef 206 | 207 | # Microsoft Azure Emulator 208 | ecf/ 209 | rcf/ 210 | 211 | # Windows Store app package directories and files 212 | AppPackages/ 213 | BundleArtifacts/ 214 | Package.StoreAssociation.xml 215 | _pkginfo.txt 216 | *.appx 217 | 218 | # Visual Studio cache files 219 | # files ending in .cache can be ignored 220 | *.[Cc]ache 221 | # but keep track of directories ending in .cache 222 | !?*.[Cc]ache/ 223 | 224 | # Others 225 | ClientBin/ 226 | ~$* 227 | *~ 228 | *.dbmdl 229 | *.dbproj.schemaview 230 | *.jfm 231 | *.pfx 232 | *.publishsettings 233 | orleans.codegen.cs 234 | 235 | # Including strong name files can present a security risk 236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 237 | #*.snk 238 | 239 | # Since there are multiple workflows, uncomment next line to ignore bower_components 240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 241 | #bower_components/ 242 | # ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true 243 | **/wwwroot/lib/ 244 | 245 | # RIA/Silverlight projects 246 | Generated_Code/ 247 | 248 | # Backup & report files from converting an old project file 249 | # to a newer Visual Studio version. Backup files are not needed, 250 | # because we have git ;-) 251 | _UpgradeReport_Files/ 252 | Backup*/ 253 | UpgradeLog*.XML 254 | UpgradeLog*.htm 255 | ServiceFabricBackup/ 256 | *.rptproj.bak 257 | 258 | # SQL Server files 259 | *.mdf 260 | *.ldf 261 | *.ndf 262 | 263 | # Business Intelligence projects 264 | *.rdl.data 265 | *.bim.layout 266 | *.bim_*.settings 267 | *.rptproj.rsuser 268 | *- Backup*.rdl 269 | 270 | # Microsoft Fakes 271 | FakesAssemblies/ 272 | 273 | # GhostDoc plugin setting file 274 | *.GhostDoc.xml 275 | 276 | # Node.js Tools for Visual Studio 277 | .ntvs_analysis.dat 278 | node_modules/ 279 | 280 | # Visual Studio 6 build log 281 | *.plg 282 | 283 | # Visual Studio 6 workspace options file 284 | *.opt 285 | 286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 287 | *.vbw 288 | 289 | # Visual Studio LightSwitch build output 290 | **/*.HTMLClient/GeneratedArtifacts 291 | **/*.DesktopClient/GeneratedArtifacts 292 | **/*.DesktopClient/ModelManifest.xml 293 | **/*.Server/GeneratedArtifacts 294 | **/*.Server/ModelManifest.xml 295 | _Pvt_Extensions 296 | 297 | # Paket dependency manager 298 | .paket/paket.exe 299 | paket-files/ 300 | 301 | # FAKE - F# Make 302 | .fake/ 303 | 304 | # JetBrains Rider 305 | .idea/ 306 | *.sln.iml 307 | 308 | # CodeRush personal settings 309 | .cr/personal 310 | 311 | # Python Tools for Visual Studio (PTVS) 312 | __pycache__/ 313 | *.pyc 314 | 315 | # Cake - Uncomment if you are using it 316 | # tools/** 317 | # !tools/packages.config 318 | 319 | # Tabs Studio 320 | *.tss 321 | 322 | # Telerik's JustMock configuration file 323 | *.jmconfig 324 | 325 | # BizTalk build output 326 | *.btp.cs 327 | *.btm.cs 328 | *.odx.cs 329 | *.xsd.cs 330 | 331 | # OpenCover UI analysis results 332 | OpenCover/ 333 | 334 | # Azure Stream Analytics local run output 335 | ASALocalRun/ 336 | 337 | # MSBuild Binary and Structured Log 338 | *.binlog 339 | 340 | # NVidia Nsight GPU debugger configuration file 341 | *.nvuser 342 | 343 | # MFractors (Xamarin productivity tool) working folder 344 | .mfractor/ 345 | 346 | # Local History for Visual Studio 347 | .localhistory/ 348 | 349 | # BeatPulse healthcheck temp database 350 | healthchecksdb 351 | 352 | # End of https://www.gitignore.io/api/ansible,visualstudio 353 | 354 | # Files created by ansbile playbook 355 | compiled/* 356 | logs/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ansible-vyos 2 | 3 | This project is capable to create configurations for VyOS devices and applying them to device. 4 | As well you can use this project for devices with system: 5 | * vyatta, 6 | * edgeOS. 7 | 8 | VyOS is a very good project for VPN IPsec endpoint. 9 | 10 | ## Getting Started 11 | 12 | ### Prerequisites 13 | 14 | Requirements needed by that project 15 | 16 | ``` 17 | - pip 18 | - ansible 19 | - napalm 20 | - napalm-base 21 | - napalm-ansible 22 | - napalm-vyos 23 | ``` 24 | 25 | ### Installing at Ubuntu 26 | 27 | * Install python-pip on ubuntu 16.04: 28 | 29 | ``` 30 | sudo apt install python-pip 31 | ``` 32 | * Install other packages from pip on ubuntu 16.04: 33 | ``` 34 | pip install -r requirements.txt 35 | ``` 36 | 37 | ### Configure ansible to use napalm 38 | 39 | After napalm instalation you need to configure proper path to library at ansible.cfg file. Example is below. 40 | 41 | ``` 42 | $ napalm-ansible 43 | To ensure Ansible can use the NAPALM modules you will have 44 | to add the following configurtion to your Ansible configuration 45 | file (ansible.cfg): 46 | 47 | [defaults] 48 | library = /Library/Python/2.7/site-packages/napalm_ansible/modules 49 | action_plugins = /Library/Python/2.7/site-packages/napalm_ansible/plugins/action 50 | 51 | For more details on ansible's configuration file visit: 52 | https://docs.ansible.com/ansible/latest/intro_configuration.html 53 | ``` 54 | 55 | ## VyOS initial configuration 56 | 57 | After instalation VyOS as a Virtual Machine or Bare Metal you need to make initial configuration. 58 | Example of commands to execute at VyOS console you can find below. It's enable ssh service, create user vyos and enable dhcp-client service at eth0 interface. 59 | 60 | ``` 61 | set service ssh 62 | set system login user vyos authentication plaintext-password vyos 63 | set interfaces ethernet eth0 address dhcp 64 | commit 65 | save 66 | ``` 67 | 68 | From managment server execute command ssh-copy-id to copy ssh public key from server to VyOS. 69 | 70 | ``` 71 | $ ssh-copy-id -i ~/.ssh/id_rsa vyos@svpn-aws-1 72 | ``` 73 | 74 | ## Add device to configuration 75 | 76 | ### Add device at inventory file 77 | ``` 78 | [svpnprod] 79 | svpn-aws-1 ansible_ssh_host=10.0.0.1 80 | svpn-aws-2 ansible_ssh_host=10.0.0.2 81 | 82 | ``` 83 | 84 | ### Add device to host_vars 85 | 86 | At host_vars directory you can keep configuration at two styles. 87 | 88 | * add one yml file with all configuration at host_vars directory 89 | 90 | ``` 91 | host_vars 92 | |-svpn-aws-1.yml 93 | ``` 94 | * add direcotry with configuration at host_vars directory 95 | ``` 96 | host_vars 97 | |-svpn-aws-1 98 | |-bgp_config.yml 99 | |-bgp_neighbour_ebgp.yml 100 | |-ipsec.yml 101 | |-svpn-aws-1.yml 102 | ``` 103 | 104 | Common configuration for a group of devices you can put to group_vars directory 105 | ``` 106 | group-vars 107 | |-svpnprod 108 | |-routing-options.yml 109 | |-policy_prefix_list.yml 110 | |-policy_statement.yml 111 | |-system_accounts.yml 112 | ``` 113 | 114 | ## Build configuration and assemble to one file 115 | Example how to build and compile configuration for devices you can find below. 116 | 117 | ``` 118 | ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=build,compile 119 | ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=build,compile -l svpn-aws-1 120 | ``` 121 | 122 | ## Dry-run before deploy 123 | 124 | Example how to check if configuration can be deploy to device you can find below. 125 | 126 | ``` 127 | ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=deploy --check 128 | ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=deploy -l svpn-aws-1 --check 129 | ``` 130 | 131 | This dry-run is very usefull to check what changes will be made at VyOS device. 132 | Diff from dry-run you can find at logs directory 133 | ``` 134 | $ cat logs/svpn-aws-2/svpn-aws-2.diff 135 | [edit protocols] 136 | +bgp 65065 { 137 | + neighbor 169.254.44.193 { 138 | + description "AMZ BGP session 1" 139 | + remote-as 64512 140 | + } 141 | + parameters { 142 | + graceful-restart { 143 | + stalepath-time 300 144 | + } 145 | + } 146 | +} 147 | [edit] 148 | ``` 149 | 150 | ## Deploy configuration to device 151 | 152 | Example how to deploy configuration for device you can find below. 153 | 154 | ``` 155 | ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=deploy 156 | ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=deploy -l svpn-aws-1 157 | ``` 158 | 159 | Example output from execution of playbook. 160 | ``` 161 | $ ansible-playbook -i inventory.ini playbook_napalm_commit.yml --tags=deploy --check 162 | 163 | PLAY [Prepare dirs] ************************************************************************************************************************************************ 164 | 165 | PLAY [Check version of VyOS] *************************************************************************************************************************************** 166 | 167 | PLAY [Generate configs for vyos] *********************************************************************************************************************************** 168 | 169 | PLAY [Assemble and Generate configuration] ************************************************************************************************************************* 170 | 171 | PLAY [Provision configuration to devices] ************************************************************************************************************************** 172 | 173 | TASK [Install new configuration] *********************************************************************************************************************************** 174 | ok: [svpn-aws-1] 175 | changed: [svpn-aws-2] 176 | 177 | PLAY RECAP ********************************************************************************************************************************************************* 178 | svpn-aws-1 : ok=1 changed=0 unreachable=0 failed=0 179 | svpn-aws-2 : ok=1 changed=1 unreachable=0 failed=0 180 | ``` 181 | 182 | 183 | ## All configuration option for roles you can find here 184 | 185 | * [BGP Role](roles/bgp/README.md) 186 | * [Firewall Role](roles/firewall/README.md) 187 | * [Interfaces Role](roles/interfaces/README.md) 188 | * [IPsec Role](roles/ipsec/README.md) 189 | * [NAT Role](roles/nat/README.md) 190 | * [Policy Role](roles/policy/README.md) 191 | * [Protocols Role](roles/protocols/README.md) 192 | * [System Role](roles/system/README.md) 193 | 194 | ## Built With 195 | 196 | * [Ansible](https://www.ansible.com/) - Ansible home page 197 | * [Napalm](https://napalm-automation.net/) - NAPALM home page 198 | 199 | ## Authors 200 | * **Netork Team at DreamLab** 201 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | library = /Library/Python/2.7/site-packages/napalm_ansible/modules 3 | action_plugins = /Library/Python/2.7/site-packages/napalm_ansible/plugins/action 4 | hash_behaviour = merge -------------------------------------------------------------------------------- /get_facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Assemble and Generate configuration 4 | hosts: all 5 | connection: local 6 | gather_facts: no 7 | 8 | tasks: 9 | - name: get facts from device 10 | napalm_get_facts: 11 | hostname={{ inventory_hostname }} 12 | username=ansible 13 | password=ansible123 14 | dev_os={{ os }} 15 | filter='facts,interfaces,bgp_neighbors' 16 | register: result 17 | 18 | - debug: var=result 19 | -------------------------------------------------------------------------------- /group_vars/svpnprod/policy_prefix_list.yml: -------------------------------------------------------------------------------- 1 | --- 2 | policy_prefix_list: 3 | "pfx-announce-to-aws": 4 | prefixes: 5 | - "10.0.0.0/24" 6 | 7 | "pfx-amazon-vpcs": 8 | prefixes: 9 | - "172.16.0.0/24" 10 | -------------------------------------------------------------------------------- /group_vars/svpnprod/policy_statement.yml: -------------------------------------------------------------------------------- 1 | --- 2 | policy_statement: 3 | "policy-amazon-in": 4 | terms: 5 | - name: "amazon-vpcs" 6 | from: 7 | prefix_list: "pfx-amazon-vpcs" 8 | then: 9 | action: "accept" 10 | - name: "default" 11 | then: 12 | action: "reject" 13 | "policy-amazon-out": 14 | terms: 15 | - name: "Oout" 16 | from: 17 | prefix_list: "pfx-announce-to-aws" 18 | then: 19 | action: "accept" 20 | metric: "100" 21 | origin: "igp" 22 | - name: "default" 23 | then: 24 | action: "reject" 25 | -------------------------------------------------------------------------------- /group_vars/svpnprod/routing_options.yml: -------------------------------------------------------------------------------- 1 | --- 2 | routing_options: 3 | main: 4 | graceful_restart: "yes" 5 | router_id: "{{system_main_address_ipv4}}" 6 | asn: "65065" 7 | -------------------------------------------------------------------------------- /group_vars/svpnprod/system_accounts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system_accounts: 3 | - login: ansible 4 | encryptedpass: "$6$No1ZFhDEY2ypjxN$vsXnI/cU3lZcCZt2FeY8VChNoXJ27hziJTg6XIP14fagY48TT.OYj8/2IQyBMihl0eoNDD1gpp2haeblQ8nNU1" 5 | fullname: "Ansible account" 6 | uid: "2001" 7 | level: "admin" 8 | - login: vyos 9 | encryptedpass: "$1$EckAeduc$dED6eP8sP/lSzWy33oezL." 10 | fullname: "Vyos account" 11 | uid: "2002" 12 | level: "admin" 13 | -------------------------------------------------------------------------------- /host_vars/svpn-aws-1/bgp_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | bgp_config: 3 | main: 4 | graceful_restart: "yes" 5 | group: 6 | ebgp: 7 | description: "BGP to Amazon" 8 | 9 | networks: 10 | - "10.0.0.0/24" -------------------------------------------------------------------------------- /host_vars/svpn-aws-1/bgp_neighbors_ebgp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | bgp_neighbors_ebgp: 3 | "amazon_bgp1_ipv4": 4 | peer_ip: "169.254.44.193" 5 | peer_as: "64512" 6 | description: "AMZ BGP session 1" 7 | import: "policy-amazon-in" 8 | export: "policy-amazon-out" 9 | member_of: "ebgp" 10 | bind_router: "svpn-aws-1" 11 | -------------------------------------------------------------------------------- /host_vars/svpn-aws-1/ipsec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ipsec_interface: dum1 3 | ipsec_nat_traversal: enable 4 | 5 | ipsec_esp: 6 | - name: "AWS" 7 | compression: "disable" 8 | lifetime: "3600" 9 | mode: "tunnel" 10 | pfs: "enable" 11 | proposal: 12 | - { encryption: "aes128", hash: "sha1" } 13 | - name: "ESP-1W" 14 | lifetime: "28800" 15 | mode: "tunnel" 16 | pfs: "dh-group5" 17 | proposal: 18 | - { encryption: "3des", hash: "sha1" } 19 | - name: "ESP-1W-AES" 20 | lifetime: "28800" 21 | mode: "tunnel" 22 | pfs: "dh-group5" 23 | proposal: 24 | - { encryption: "aes256", hash: "sha1" } 25 | 26 | ipsec_isakmp: 27 | - name: "AWS" 28 | dpd_config: 29 | - {dpd_action: "restart", dpd_interval: "15", dpd_timeout: "30" } 30 | ikev2_reauth: "no" 31 | key_exchange: "ikev1" 32 | lifetime: "28800" 33 | proposal: 34 | - { dh_group: "2", encryption: "aes128", hash: "sha1" } 35 | - name: "IKE-1W" 36 | lifetime: "86400" 37 | proposal: 38 | - { dh_group: "2", encryption: "3des", hash: "sha1" } 39 | - name: "IKE-1W-AES" 40 | lifetime: "86400" 41 | proposal: 42 | - { dh_group: "2", encryption: "3des", hash: "sha1" } 43 | 44 | ipsec_peers: 45 | - peerip: "192.168.56.12" 46 | description: "to other vyos" 47 | authentication_mode: "pre-shared-secret" 48 | autehntication_data: "123qwe" 49 | ike_group: "IKE-1W" 50 | connection_type: "initiate" 51 | ikev2_reauth: "no" 52 | default_esp_group: "ESP-1W" 53 | vti: "vti0" 54 | 55 | ipsec_vti: 56 | - iface: "vti0" 57 | local_ip: "169.254.44.194" 58 | remote_ip: "169.254.44.193" 59 | mask: "30" 60 | 61 | -------------------------------------------------------------------------------- /host_vars/svpn-aws-1/svpn-aws-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | os: vyos 3 | 4 | system_hostname: "svpn-aws-1" 5 | 6 | system_ntp: 7 | - {address: "4.pool.ntp.org"} 8 | - {address: "2.pool.ntp.org"} 9 | 10 | system_dns: 11 | - "1.1.1.1" 12 | - "8.8.8.8" 13 | system_snmp: 14 | contact: "a@b.com" 15 | location: "Galaxy" 16 | listen_interface: "eth0" 17 | communities: 18 | public: 19 | authorization: "ro" 20 | clients: 21 | - "11.11.11.11" 22 | - "10.10.10.11" 23 | system_timezone: "Europe/Warsaw" 24 | 25 | system_banner: > 26 | PRODUCTION NETWORK UNAUTHORIZED USE OF THIS SYSTEM IS PROHIBITED! 27 | 28 | system_interfaces: 29 | eth0: 30 | type: "ethernet" 31 | address: "192.168.138.237/24" 32 | description: "management" 33 | dum1: 34 | type: "dummy" 35 | address: "172.16.3.1/24" 36 | description: "inside" 37 | dum2: 38 | type: "dummy" 39 | address: "172.16.5.1/24" 40 | description: "outside" 41 | 42 | policy_mss_value: "1400" 43 | policy_mss_interface: "dum1" 44 | 45 | system_main_address_ipv4: "1.1.1.1" 46 | 47 | nat_source_rules: 48 | - {description: "ru1", source_address: "192.168.200.0/24", 49 | outbound_interface: "dum2", translation_address: "172.16.3.1-172.16.3.100"} 50 | 51 | firewall_rules: 52 | - name: "example_acl_2" 53 | default_action: "drop" 54 | rules: 55 | - {action: "accept", protocol: "icmp"} 56 | - {action: "accept", destination_address: "192.168.0.0/16", destination_port: "80", protocol: "tcp"} 57 | - {action: "accept", destination_address: "1.2.3.5/32", destination_port: "53", source_address: "4.2.4.4/32", source_port: "1024-65535", protocol: "tcp_udp"} 58 | - {action: "accept", destination_port: "53"} 59 | firewall_interfaces: 60 | dum2: 61 | out: "example_acl_2" 62 | 63 | 64 | -------------------------------------------------------------------------------- /host_vars/svpn-aws-2/bgp_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | bgp_config: 3 | main: 4 | graceful_restart: "yes" 5 | group: 6 | ebgp: 7 | description: "BGP to Amazon" 8 | 9 | networks: 10 | - "10.0.0.0/24" -------------------------------------------------------------------------------- /host_vars/svpn-aws-2/bgp_neighbors_ebgp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | bgp_neighbors_ebgp: 3 | "amazon_bgp1_ipv4": 4 | peer_ip: "169.254.44.193" 5 | peer_as: "64512" 6 | description: "AMZ BGP session 1" 7 | import: "policy-amazon-in" 8 | export: "policy-amazon-out" 9 | member_of: "ebgp" 10 | bind_router: "svpn-aws-2" 11 | -------------------------------------------------------------------------------- /host_vars/svpn-aws-2/ipsec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ipsec_interface: dum1 3 | ipsec_nat_traversal: enable 4 | 5 | ipsec_esp: 6 | - name: "AWS" 7 | compression: "disable" 8 | lifetime: "3600" 9 | mode: "tunnel" 10 | pfs: "enable" 11 | proposal: 12 | - { encryption: "aes128", hash: "sha1" } 13 | - name: "ESP-1W" 14 | lifetime: "28800" 15 | mode: "tunnel" 16 | pfs: "dh-group5" 17 | proposal: 18 | - { encryption: "3des", hash: "sha1" } 19 | - name: "ESP-1W-AES" 20 | lifetime: "28800" 21 | mode: "tunnel" 22 | pfs: "dh-group5" 23 | proposal: 24 | - { encryption: "aes256", hash: "sha1" } 25 | 26 | ipsec_isakmp: 27 | - name: "AWS" 28 | dpd_config: 29 | - {dpd_action: "restart", dpd_interval: "15", dpd_timeout: "30" } 30 | ikev2_reauth: "no" 31 | key_exchange: "ikev1" 32 | lifetime: "28800" 33 | proposal: 34 | - { dh_group: "2", encryption: "aes128", hash: "sha1" } 35 | - name: "IKE-1W" 36 | lifetime: "86400" 37 | proposal: 38 | - { dh_group: "2", encryption: "3des", hash: "sha1" } 39 | - name: "IKE-1W-AES" 40 | lifetime: "86400" 41 | proposal: 42 | - { dh_group: "2", encryption: "3des", hash: "sha1" } 43 | 44 | ipsec_peers: 45 | - peerip: "192.168.56.12" 46 | description: "to other vyos" 47 | authentication_mode: "pre-shared-secret" 48 | autehntication_data: "123qwe" 49 | ike_group: "IKE-1W" 50 | connection_type: "initiate" 51 | ikev2_reauth: "no" 52 | default_esp_group: "ESP-1W" 53 | vti: "vti0" 54 | 55 | ipsec_vti: 56 | - iface: "vti0" 57 | local_ip: "169.254.44.194" 58 | remote_ip: "169.254.44.193" 59 | mask: "30" 60 | 61 | -------------------------------------------------------------------------------- /host_vars/svpn-aws-2/svpn-aws-2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | os: vyos 3 | 4 | system_hostname: "svpn-aws-2" 5 | 6 | system_ntp: 7 | - { address: "4.pool.ntp.org" } 8 | - { address: "2.pool.ntp.org" } 9 | 10 | system_dns: 11 | - "1.1.1.1" 12 | - "8.8.8.8" 13 | system_snmp: 14 | contact: "a@b.com" 15 | location: "Galaxy" 16 | listen_interface: "eth0" 17 | communities: 18 | public: 19 | authorization: "ro" 20 | clients: 21 | - "11.11.11.11" 22 | - "10.10.10.11" 23 | system_timezone: "Europe/Warsaw" 24 | 25 | system_banner: > 26 | PRODUCTION NETWORK UNAUTHORIZED USE OF THIS SYSTEM IS PROHIBITED! 27 | 28 | system_interfaces: 29 | eth0: 30 | type: "ethernet" 31 | address: "192.168.138.242/24" 32 | description: "management" 33 | dum1: 34 | type: "dummy" 35 | address: "172.16.3.1/24" 36 | description: "inside" 37 | dum2: 38 | type: "dummy" 39 | address: "172.16.5.1/24" 40 | description: "outside" 41 | 42 | policy_mss_value: "1400" 43 | policy_mss_interface: "dum1" 44 | 45 | system_main_address_ipv4: "1.1.1.1" 46 | 47 | nat_source_rules: 48 | - { 49 | description: "ru1", 50 | source_address: "192.168.200.0/24", 51 | outbound_interface: "dum2", 52 | translation_address: "172.16.3.1-172.16.3.100", 53 | } 54 | 55 | firewall_rules: 56 | - name: "example_acl_2" 57 | default_action: "drop" 58 | rules: 59 | - { action: "accept", protocol: "icmp" } 60 | - { 61 | action: "accept", 62 | destination_address: "192.168.0.0/16", 63 | destination_port: "80", 64 | protocol: "tcp", 65 | } 66 | - { 67 | action: "accept", 68 | destination_address: "1.2.3.5/32", 69 | destination_port: "53", 70 | source_address: "4.2.4.4/32", 71 | source_port: "1024-65535", 72 | protocol: "tcp_udp", 73 | } 74 | - { action: "accept", destination_port: "53" } 75 | firewall_interfaces: 76 | dum2: 77 | out: "example_acl_2" 78 | -------------------------------------------------------------------------------- /inventory.ini: -------------------------------------------------------------------------------- 1 | [svpnprod] 2 | svpn-aws-1 ansible_ssh_host=192.168.138.237 3 | svpn-aws-2 ansible_ssh_host=192.168.138.242 4 | 5 | 6 | [svpnprod:vars] 7 | ansible_ssh_port=22 8 | ansible_ssh_user=vyos 9 | ansible_ssh_password=vyos 10 | -------------------------------------------------------------------------------- /library/check_bgp_status: -------------------------------------------------------------------------------- 1 | check_bgp_status.py -------------------------------------------------------------------------------- /library/check_bgp_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from ansible.module_utils.basic import * 4 | 5 | 6 | def main(): 7 | """Main module""" 8 | module = AnsibleModule( 9 | argument_spec=dict( 10 | device_name=dict(type='str', required=True), 11 | bgp_neighbors=dict(type='dict', required=True), 12 | ), 13 | ) 14 | device_name = module.params['device_name'] 15 | bgp_neighbors = module.params['bgp_neighbors'] 16 | 17 | result = [] 18 | check_result = True 19 | peerup = 0 20 | peerdown = 0 21 | 22 | if ( bgp_neighbors.has_key('global') 23 | and bgp_neighbors['global'].has_key('peers')): 24 | for peer in bgp_neighbors['global']['peers']: 25 | if not bgp_neighbors['global']['peers'][peer]['is_up']: 26 | check_result = False 27 | msg="Device: {} Peer {} is down".format(device_name, peer) 28 | result.append(msg) 29 | peerdown += 1 30 | else: 31 | peerup += 1 32 | 33 | summary_status = "Number of peers up: {} , peers down {}".format(peerup, 34 | peerdown) 35 | 36 | if check_result: 37 | module.exit_json(msg=summary_status) 38 | else: 39 | result.insert(0, summary_status) 40 | module.fail_json(msg='\n'.join(result), check_result=check_result) 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /linter.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for file in $(find . -name "*.yml") 4 | do 5 | yamllint $file 6 | rc=$? 7 | if [ "$rc" -ne 0 ] ; then 8 | exit $rc 9 | fi 10 | done 11 | 12 | echo "TEST PASSED all *.yml files are correct" 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /napalm_example.py: -------------------------------------------------------------------------------- 1 | #vyos2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2200 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='/home/piotr/.vagrant.d/insecure_private_key' 2 | 3 | key_file='/root/.vagrant.d/insecure_private_key' 4 | 5 | 6 | devicearg = { 7 | 'hostname': '127.0.0.1', 8 | 'username': 'vagrant', 9 | 'password': 'dummypass', 10 | 'optional_args': {'port': 2222, 'key_file': key_file}, 11 | } 12 | 13 | import os 14 | 15 | from napalm import get_network_driver 16 | driver = get_network_driver('vyos') 17 | 18 | mydevice = driver(**devicearg) 19 | mydevice.open() 20 | 21 | 22 | print mydevice.load_replace_candidate(filename='./compiled/vyos2/running.conf') 23 | print mydevice.compare_config() 24 | #mydevice.discard_config() 25 | mydevice.commit_config() 26 | -------------------------------------------------------------------------------- /napalm_example_set.py: -------------------------------------------------------------------------------- 1 | #vyos2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2200 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='/home/piotr/.vagrant.d/insecure_private_key' 2 | 3 | key_file='/root/.vagrant.d/insecure_private_key' 4 | 5 | 6 | devicearg = { 7 | 'hostname': '127.0.0.1', 8 | 'username': 'vagrant', 9 | 'password': 'dummypass', 10 | 'optional_args': {'port': 2222, 'key_file': key_file}, 11 | } 12 | 13 | import os 14 | 15 | from napalm import get_network_driver 16 | driver = get_network_driver('vyos') 17 | 18 | mydevice = driver(**devicearg) 19 | mydevice.open() 20 | 21 | 22 | print mydevice.load_merge_candidate(filename='./compiled/vyos2/command_set.conf') 23 | print mydevice.compare_config() 24 | #mydevice.discard_config() 25 | mydevice.commit_config() 26 | -------------------------------------------------------------------------------- /playbook_check.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check VyOS BGP Sessions 3 | hosts: svpnprod 4 | connection: local 5 | gather_facts: no 6 | tags: check 7 | tasks: 8 | - name: get bgp neighbors from device 9 | napalm_get_facts: 10 | hostname: "{{ ansible_ssh_host | default('vyos') }}" 11 | username: "{{ ansible_ssh_user | default('vyos') }}" 12 | password: "{{ ansible_ssh_password | default('vyos') }}" 13 | dev_os: "{{ os }}" 14 | optional_args: "{'port': {{ansible_ssh_port | default('22')}} }" 15 | filter: 'bgp_neighbors' 16 | register: result 17 | - name: Check BGP Status 18 | check_bgp_status: 19 | device_name: "{{ inventory_hostname }}" 20 | bgp_neighbors: "{{ result }}" 21 | -------------------------------------------------------------------------------- /playbook_napalm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # test playbook 3 | - name: Prepare dirs 4 | hosts: svpnprod 5 | gather_facts: no 6 | connection: local 7 | 8 | tasks: 9 | - name: Remove old config 10 | file: path={{ playbook_dir }}/compiled/{{ inventory_hostname }} state=absent 11 | register: baseconfdir 12 | tags: build 13 | changed_when: False 14 | 15 | - name: Create empty 16 | file: > 17 | path={{ playbook_dir }}/compiled/{{ inventory_hostname }} state=directory 18 | tags: build 19 | changed_when: False 20 | 21 | - name: Remove old log directory 22 | file: path={{ playbook_dir }}/logs/{{ inventory_hostname }} state=absent 23 | register: baselogdir 24 | tags: build 25 | changed_when: False 26 | 27 | - name: Create empty log dir 28 | file: path={{ playbook_dir }}/logs/{{ inventory_hostname }} state=directory 29 | tags: build 30 | changed_when: False 31 | 32 | - name: Static configs directory 33 | file: path={{ playbook_dir }}/staticfiles state=directory 34 | register: basestaticdir 35 | tags: build 36 | changed_when: False 37 | 38 | - name: Check version of VyOS 39 | hosts: svpnprod 40 | gather_facts: no 41 | tags: build 42 | 43 | tasks: 44 | - name: Check if FRR directory exists. 45 | stat: 46 | path: /etc/frr/ 47 | register: vyos_frr_daemon 48 | 49 | - name: Generate configs for vyos 50 | hosts: svpnprod 51 | gather_facts: no 52 | connection: local 53 | tags: build 54 | 55 | roles: 56 | - system 57 | - protocols 58 | - policy 59 | - ipsec 60 | - nat 61 | - firewall 62 | - interfaces 63 | - bgp 64 | 65 | - name: Assemble and Generate configuration 66 | hosts: svpnprod 67 | connection: local 68 | gather_facts: no 69 | tags: compile 70 | 71 | tasks: 72 | - name: Assemble configuration 73 | assemble: > 74 | src: "{{ playbook_dir }}/compiled/{{ inventory_hostname }}" 75 | dest: "{{ playbook_dir }}/compiled/{{ inventory_hostname }}/running.conf" 76 | changed_when: False 77 | 78 | - name: Provision configuration to devices 79 | hosts: svpnprod 80 | connection: local 81 | gather_facts: no 82 | tags: deploy 83 | tasks: 84 | - name: Install new configuration 85 | napalm_install_config: 86 | hostname: "{{ ansible_ssh_host | default('vyos') }}" 87 | username: "{{ ansible_ssh_user | default('vyos') }}" 88 | password: "{{ ansible_ssh_password | default('vyos') }}" 89 | dev_os: "{{ os }}" 90 | optional_args: "{'port': {{ansible_ssh_port | default('22')}} }" 91 | config_file: "compiled/{{inventory_hostname}}/running.conf" 92 | replace_config: true 93 | commit_changes: false 94 | get_diffs: true 95 | diff_file: "logs/{{inventory_hostname}}/{{inventory_hostname}}.diff" 96 | -------------------------------------------------------------------------------- /playbook_napalm_commit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # test playbook 3 | - name: Prepare dirs 4 | hosts: svpnprod 5 | gather_facts: no 6 | connection: local 7 | 8 | tasks: 9 | - name: Remove old config 10 | file: path={{ playbook_dir }}/compiled/{{ inventory_hostname }} state=absent 11 | register: baseconfdir 12 | tags: build 13 | changed_when: False 14 | 15 | - name: Create empty 16 | file: > 17 | path={{ playbook_dir }}/compiled/{{ inventory_hostname }} state=directory 18 | tags: build 19 | changed_when: False 20 | 21 | - name: Remove old log directory 22 | file: path={{ playbook_dir }}/logs/{{ inventory_hostname }} state=absent 23 | register: baselogdir 24 | tags: build 25 | changed_when: False 26 | 27 | - name: Create empty log dir 28 | file: path={{ playbook_dir }}/logs/{{ inventory_hostname }} state=directory 29 | tags: build 30 | changed_when: False 31 | 32 | - name: Static configs directory 33 | file: path={{ playbook_dir }}/staticfiles state=directory 34 | register: basestaticdir 35 | tags: build 36 | changed_when: False 37 | 38 | - name: Check version of VyOS 39 | hosts: svpnprod 40 | gather_facts: no 41 | tags: build 42 | 43 | tasks: 44 | - name: Check if FRR directory exists. 45 | stat: 46 | path: /etc/frr/ 47 | register: vyos_frr_daemon 48 | 49 | - name: Generate configs for vyos 50 | hosts: svpnprod 51 | gather_facts: no 52 | connection: local 53 | tags: build 54 | 55 | roles: 56 | - system 57 | - protocols 58 | - policy 59 | - ipsec 60 | - nat 61 | - firewall 62 | - interfaces 63 | - bgp 64 | 65 | - name: Assemble and Generate configuration 66 | hosts: svpnprod 67 | connection: local 68 | gather_facts: no 69 | tags: compile 70 | 71 | tasks: 72 | - name: Assemble configuration 73 | assemble: > 74 | src: "{{ playbook_dir }}/compiled/{{ inventory_hostname }}" 75 | dest: "{{ playbook_dir }}/compiled/{{ inventory_hostname }}/running.conf" 76 | changed_when: False 77 | 78 | - name: Provision configuration to devices 79 | hosts: [svpnprod] 80 | connection: local 81 | gather_facts: no 82 | tags: deploy 83 | tasks: 84 | - name: Install new configuration 85 | napalm_install_config: 86 | hostname: "{{ ansible_ssh_host | default('vyos') }}" 87 | username: "{{ ansible_ssh_user | default('vyos') }}" 88 | password: "{{ ansible_ssh_password | default('vyos') }}" 89 | dev_os: "{{ os }}" 90 | optional_args: "{'port': {{ansible_ssh_port | default('22')}} }" 91 | config_file: "compiled/{{inventory_hostname}}/running.conf" 92 | replace_config: true 93 | commit_changes: true 94 | get_diffs: true 95 | diff_file: "logs/{{inventory_hostname}}/{{inventory_hostname}}.diff" 96 | -------------------------------------------------------------------------------- /playbook_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # test playbook 3 | - name: Prepare dirs 4 | hosts: svpnprod 5 | gather_facts: no 6 | connection: local 7 | 8 | tasks: 9 | - name: Remove old config 10 | file: path={{ playbook_dir }}/compiled/{{ inventory_hostname }} state=absent 11 | register: baseconfdir 12 | tags: build 13 | changed_when: False 14 | 15 | - name: Create empty 16 | file: > 17 | path={{ playbook_dir }}/compiled/{{ inventory_hostname }} state=directory 18 | tags: build 19 | changed_when: False 20 | 21 | - name: Remove old log directory 22 | file: path={{ playbook_dir }}/logs/{{ inventory_hostname }} state=absent 23 | register: baselogdir 24 | tags: build 25 | changed_when: False 26 | 27 | - name: Create empty log dir 28 | file: path={{ playbook_dir }}/logs/{{ inventory_hostname }} state=directory 29 | tags: build 30 | changed_when: False 31 | 32 | - name: Static configs directory 33 | file: path={{ playbook_dir }}/staticfiles state=directory 34 | register: basestaticdir 35 | tags: build 36 | changed_when: False 37 | 38 | - name: Generate configs for vyos 39 | hosts: svpnprod 40 | gather_facts: no 41 | connection: local 42 | tags: build 43 | 44 | roles: 45 | - system 46 | - protocols 47 | - policy 48 | - ipsec 49 | - nat 50 | - firewall 51 | - interfaces 52 | - bgp 53 | 54 | - name: Assemble and Generate configuration 55 | hosts: svpnprod 56 | connection: local 57 | gather_facts: no 58 | tags: compile 59 | 60 | tasks: 61 | - name: Assemble configuration 62 | assemble: > 63 | src: "{{ playbook_dir }}/compiled/{{ inventory_hostname }}" 64 | dest: "{{ playbook_dir }}/compiled/{{ inventory_hostname }}/running.conf" 65 | changed_when: False 66 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ansible 2 | napalm 3 | napalm-base 4 | napalm-ansible 5 | napalm-vyos -------------------------------------------------------------------------------- /roles/bgp/README.md: -------------------------------------------------------------------------------- 1 | # 'bgp' and 'routing-options role 2 | Generate configuration for the bgp routing protocol and routing-options 3 | Currently supported os: vyos 4 | 5 | Features: 6 | - bgp config (networks, aggregates, graceful restart) 7 | - ibgp neighbour 8 | - ebgp neighbour 9 | 10 | ## Variables needed by the template vyos example 11 | 12 | Routing Options Configuration 13 | 14 | ```yaml 15 | 16 | routing_options: 17 | main: # logical sytem name - main is default logical system name, required 18 | graceful_restart: "yes" # optional 19 | router_id: # router id option is set by "system_main_address_ipv4" 20 | asn: "65065" # router loacal ASN 21 | 22 | ``` 23 | 24 | BGP configuration 25 | 26 | ```yaml 27 | 28 | bgp_config: 29 | main: # logical sytem name - main is default logical system name, required 30 | graceful_restart: "yes" # optional 31 | group: # enable bgp neighbour groups, optional 32 | groupname: # bgp neighbour group name, required example ibgp, ebgp 33 | description: "some-description" # bgp group description, optional 34 | import: ["some-policy"] # bgp group import policy, optional 35 | export: ["some-policy"] # bgp group export policy, optional 36 | ``` 37 | 38 | Example of BGP configuration 39 | 40 | ```yaml 41 | bgp_config: 42 | main: 43 | graceful_restart: "yes" 44 | group: 45 | ibgp: 46 | peer_as: "65012" 47 | ebgp: 48 | export: ["some-policy"] 49 | import: ["some-policy"] 50 | ``` 51 | 52 | BGP Neighbour configuration 53 | 54 | ```yaml 55 | bgp_neighbors_ebgp: 56 | "name": 57 | peer_ip: # peer IP 58 | peer_as: # peer ASN 59 | description: # bgp neighbour description 60 | import: # import policy 61 | export: # export policy 62 | member_of: # member of the group ibgp or ebgp 63 | bind_router: # bind BGP session to the router 64 | 65 | ``` 66 | 67 | Example of BGP Neighbour configuration 68 | 69 | ```yaml 70 | 71 | bgp_neighbors_ebgp: 72 | "router1": 73 | peer_ip: "1.1.1.1" 74 | peer_as: "65000" 75 | description: "router description" 76 | import: "some-policy" 77 | export: "some-policy" 78 | member_of: "ebgp" 79 | bind_router: "router1" 80 | 81 | bgp_neighbors_ibgp: 82 | "router2": 83 | peer_ip: "2.2.2.2" 84 | peer_as: "65012" 85 | description: "router2" 86 | import: "some-policy" 87 | export: "some-policy" 88 | member_of: "ibgp" 89 | bind_router: "router2" 90 | 91 | ```` 92 | -------------------------------------------------------------------------------- /roles/bgp/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from bgp role" 3 | template: 4 | dest: "{{baseconfdir.path}}/80_bgp.out" 5 | src: "{{os}}/bgp.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/bgp/templates/vyos/bgp.j2: -------------------------------------------------------------------------------- 1 | {% if bgp_config is defined -%} 2 | {% if vyos_frr_deamon is defined -%}} 3 | {% include "include/frr_bgp.j2" %} 4 | {% else %} 5 | {% include "include/quagga_bgp.j2" %} 6 | {% endif -%} 7 | {% endif -%} -------------------------------------------------------------------------------- /roles/bgp/templates/vyos/include/frr_bgp.j2: -------------------------------------------------------------------------------- 1 | protocols { 2 | bgp {{ routing_options['main'].asn }} { 3 | 4 | {# Template for routing options#} 5 | {% if routing_options['main'].graceful_restart == "yes" -%} 6 | parameters { 7 | graceful-restart { 8 | stalepath-time 300 9 | } 10 | } 11 | {% endif -%} 12 | 13 | {# Template for aggregate roles#} 14 | {% if routing_options is defined -%} 15 | {% if routing_options['main'].aggregate is defined -%} 16 | {% for network in routing_options['main'].aggregate -%} 17 | aggregate-address {{ network }} { 18 | } 19 | {% endfor -%} 20 | {% endif -%} 21 | {% endif -%} 22 | 23 | {# Template for network statement#} 24 | {% if bgp_config['main'].networks is defined -%} 25 | address-family { 26 | ipv4-unicast { 27 | {% for network in bgp_config['main'].networks -%} 28 | network {{ network }} { 29 | } 30 | {% endfor -%} 31 | } 32 | } 33 | {% endif -%} 34 | 35 | {# Template for eBGP sessions#} 36 | {% if bgp_neighbors_ebgp is defined -%} 37 | {% for peer in bgp_neighbors_ebgp -%} 38 | {% if bgp_neighbors_ebgp[peer].member_of == 'ebgp' and bgp_neighbors_ebgp[peer].bind_router == system_hostname -%} 39 | {% if bgp_neighbors_ebgp[peer].enabled is not defined or bgp_neighbors_ebgp[peer].enabled == "yes" %} 40 | neighbor {{bgp_neighbors_ebgp[peer].peer_ip}} { 41 | address-family { 42 | ipv4-unicast { 43 | {% if bgp_neighbors_ebgp[peer].import is defined or bgp_neighbors_ebgp[peer].export is defined %} 44 | route-map { 45 | {% if bgp_neighbors_ebgp[peer].import %}import {{bgp_neighbors_ebgp[peer].import}} 46 | {% endif -%} 47 | {% if bgp_neighbors_ebgp[peer].export %}export {{bgp_neighbors_ebgp[peer].export}} 48 | {% endif -%} 49 | } 50 | } 51 | } 52 | soft-reconfiguration { 53 | inbound 54 | } 55 | remote-as {{ bgp_neighbors_ebgp[peer].peer_as }} 56 | description "{{ bgp_neighbors_ebgp[peer].description }}" 57 | {% endif -%} 58 | } 59 | {% endif -%} 60 | {% endif -%} 61 | {% endfor -%} 62 | {% endif -%} 63 | 64 | {# Template for iBGP session#} 65 | {% if bgp_neighbors_ibgp is defined -%} 66 | {% for peer in bgp_neighbors_ibgp -%} 67 | {% if bgp_neighbors_ibgp[peer].member_of == 'ibgp' and bgp_neighbors_ibgp[peer].bind_router == system_hostname -%} 68 | {% if bgp_neighbors_ibgp[peer].enabled is not defined or bgp_neighbors_ibgp[peer].enabled == "yes" %} 69 | neighbor {{bgp_neighbors_ibgp[peer].peer_ip}} { 70 | address-family { 71 | ipv4-unicast { 72 | {% if bgp_neighbors_ibgp[peer].import is defined or bgp_neighbors_ibgp[peer].export is defined %} 73 | route-map { 74 | {% if bgp_neighbors_ibgp[peer].import %}import {{bgp_neighbors_ibgp[peer].import}} 75 | {% endif -%} 76 | {% if bgp_neighbors_ibgp[peer].export %}export {{bgp_neighbors_ibgp[peer].export}} 77 | {% endif -%} 78 | } 79 | } 80 | } 81 | soft-reconfiguration { 82 | inbound 83 | } 84 | remote-as {{ bgp_neighbors_ibgp[peer].peer_as }} 85 | description "{{ bgp_neighbors_ibgp[peer].description }}" 86 | {% endif -%} 87 | } 88 | 89 | {% endif -%} 90 | {% endif -%} 91 | {% endfor -%} 92 | {% endif -%} 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /roles/bgp/templates/vyos/include/quagga_bgp.j2: -------------------------------------------------------------------------------- 1 | protocols { 2 | bgp {{ routing_options['main'].asn }} { 3 | 4 | {# Template for routing options#} 5 | {% if routing_options['main'].graceful_restart == "yes" -%} 6 | parameters { 7 | graceful-restart { 8 | stalepath-time 300 9 | } 10 | } 11 | {% endif -%} 12 | 13 | {# Template for aggregate roles#} 14 | {% if routing_options is defined -%} 15 | {% if routing_options['main'].aggregate is defined -%} 16 | {% for network in routing_options['main'].aggregate -%} 17 | aggregate-address {{ network }} { 18 | } 19 | {% endfor -%} 20 | {% endif -%} 21 | {% endif -%} 22 | 23 | {# Template for network statement#} 24 | {% if bgp_config['main'].networks is defined -%} 25 | {% for network in bgp_config['main'].networks -%} 26 | network {{ network }} { 27 | } 28 | {% endfor -%} 29 | {% endif -%} 30 | 31 | {# Template for eBGP sessions#} 32 | {% if bgp_neighbors_ebgp is defined -%} 33 | {% for peer in bgp_neighbors_ebgp -%} 34 | {% if bgp_neighbors_ebgp[peer].member_of == 'ebgp' and bgp_neighbors_ebgp[peer].bind_router == system_hostname -%} 35 | {% if bgp_neighbors_ebgp[peer].enabled is not defined or bgp_neighbors_ebgp[peer].enabled == "yes" %} 36 | neighbor {{bgp_neighbors_ebgp[peer].peer_ip}} { 37 | {% if bgp_neighbors_ebgp[peer].import is defined or bgp_neighbors_ebgp[peer].export is defined %} 38 | route-map { 39 | {% if bgp_neighbors_ebgp[peer].import %}import {{bgp_neighbors_ebgp[peer].import}} 40 | {% endif -%} 41 | {% if bgp_neighbors_ebgp[peer].export %}export {{bgp_neighbors_ebgp[peer].export}} 42 | {% endif -%} 43 | } 44 | soft-reconfiguration { 45 | inbound 46 | } 47 | remote-as {{ bgp_neighbors_ebgp[peer].peer_as }} 48 | description "{{ bgp_neighbors_ebgp[peer].description }}" 49 | {% endif -%} 50 | } 51 | {% endif -%} 52 | {% endif -%} 53 | {% endfor -%} 54 | {% endif -%} 55 | 56 | {# Template for iBGP sessions#} 57 | {% if bgp_neighbors_ibgp is defined -%} 58 | {% for peer in bgp_neighbors_ibgp -%} 59 | {% if bgp_neighbors_ibgp[peer].member_of == 'ibgp' and bgp_neighbors_ibgp[peer].bind_router == system_hostname -%} 60 | {% if bgp_neighbors_ibgp[peer].enabled is not defined or bgp_neighbors_ibgp[peer].enabled == "yes" %} 61 | neighbor {{bgp_neighbors_ibgp[peer].peer_ip}} { 62 | {% if bgp_neighbors_ibgp[peer].import is defined or bgp_neighbors_ibgp[peer].export is defined %} 63 | route-map { 64 | {% if bgp_neighbors_ibgp[peer].import %}import {{bgp_neighbors_ibgp[peer].import}} 65 | {% endif -%} 66 | {% if bgp_neighbors_ibgp[peer].export %}export {{bgp_neighbors_ibgp[peer].export}} 67 | {% endif -%} 68 | } 69 | soft-reconfiguration { 70 | inbound 71 | } 72 | remote-as {{ bgp_neighbors_ibgp[peer].peer_as }} 73 | description "{{ bgp_neighbors_ibgp[peer].description }}" 74 | {% endif -%} 75 | } 76 | 77 | {% endif -%} 78 | {% endif -%} 79 | {% endfor -%} 80 | {% endif -%} 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /roles/firewall/README.md: -------------------------------------------------------------------------------- 1 | # 'firewall' role 2 | Generate firewall rules and configuration for interfaces (input and output filter). 3 | Currently supported os: vyos 4 | 5 | Features in the **vyos** os: 6 | - source & destination address 7 | - source & destination prefix list 8 | - source & destination port 9 | - protocol (all protocols - tcp_udp for tcp & udp protocol) 10 | - icmp packet type (for icmp protocol) 11 | - tcp established packets 12 | - default action for terms 13 | 14 | ### Parameters used in rule definition: 15 | 16 | 17 | ```yaml 18 | 19 | name: # string, name of the rule (term) - required 20 | action: # string (if single action) or array (if multiple actions), currently supported actions: 21 | # accept, drop/discard - both are correct, log, syslog, count, sample, mirror, nextterm 22 | # required 23 | source_address: # string, source address - optional 24 | destination_address: # string, destination address - optional 25 | source_port: # string or array, source port, optional 26 | destination_port: # string or array, destination port - optional 27 | protocol: # string, protocol - optional 28 | tcp_established: # string, for packets with tcp established flag - optional 29 | 30 | 31 | ``` 32 | 33 | ### Info: 34 | 35 | This template is using another template (interfaces) for binding filters to specific interface. 36 | 37 | This is possible when additional parameters are provided in interface / unit / family section: 38 | 39 | ```yaml 40 | eth0: 41 | units: 42 | 0: 43 | family: 44 | inet: 45 | filter: 46 | input: "bgp_peer_in_new" 47 | output: "bgp_peer_out" 48 | 49 | ``` 50 | 51 | 52 | ## Variables needed by the template 53 | 54 | ```yaml 55 | 56 | firewall_rules: 57 | "bgp_peer_in": # name of filter - required 58 | default_action: "accept" # default action (last action), string for single action or array ["action1", "action2"] for multiple actions - optional 59 | description: "" # description - optional 60 | rules: 61 | - {name: "T1", action: "accept", destination_address: "10.0.0.0/28"} 62 | - {name: "T2", action: "accept", protocol: "tcp", tcp_established: "yes"} 63 | - {name: "T3", action: "accept", protocol: "icmp" } 64 | - {name: "T4", action: "drop", destination_port: "bgp"} 65 | - {name: "T5", action: "accept", protocol: "tcp", destination_port: "80", destination_address: "10.0.0.0/24"} 66 | - {name: "T5", action: "accept", protocol: "tcp", destination_port: "443", destination_address: "10.0.0.0/24"} 67 | - {name: "T6", action: "drop", destination_address: "10.0.0.0/24"} 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /roles/firewall/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from firewall role" 3 | template: 4 | dest: "{{baseconfdir.path}}/70_firewall.out" 5 | src: "{{os}}/firewall.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/firewall/templates/vyos/firewall.j2: -------------------------------------------------------------------------------- 1 | 2 | {% if firewall_rules is defined -%} 3 | {% include "include/firewall_rules.j2" %} 4 | {% endif %} 5 | -------------------------------------------------------------------------------- /roles/firewall/templates/vyos/include/firewall_rules.j2: -------------------------------------------------------------------------------- 1 | 2 | firewall { 3 | {% for acls in firewall_rules -%} 4 | name {{ acls.name }} { 5 | {% if acls.default_action is defined -%} 6 | default-action {{ acls.default_action }} 7 | {% endif %} 8 | {% if acls.description is defined -%} 9 | description "{{ acls.description }}" 10 | {% endif %} 11 | {% for rule in acls.rules -%} 12 | rule {{ loop.index }} { 13 | action {{ rule.action }} 14 | {% if rule.destination_address is defined or ( rule.destination_port is defined ) -%} 15 | destination { 16 | {% if rule.destination_address is defined -%} 17 | address {{ rule.destination_address}} 18 | {% endif -%} 19 | {% if rule.destination_port is defined -%} 20 | port {{ rule.destination_port}} 21 | {% endif -%} 22 | } 23 | {% endif -%} 24 | 25 | {% if rule.protocol is defined -%} 26 | protocol {{ rule.protocol}} 27 | {% endif -%} 28 | 29 | {% if rule.protocol is undefined and (( rule.destination_port is defined ) or (rule.source_port is defined))-%} 30 | protocol tcp_udp 31 | {% endif -%} 32 | 33 | {% if rule.tcp_established is defined -%} 34 | state { 35 | established enable 36 | related enable 37 | } 38 | {% endif -%} 39 | 40 | {% if rule.source_address is defined or ( rule.source_port is defined ) -%} 41 | source { 42 | {% if rule.source_address is defined -%} 43 | address {{ rule.source_address}} 44 | {% endif -%} 45 | {% if rule.source_port is defined -%} 46 | port {{ rule.source_port}} 47 | {% endif -%} 48 | } 49 | {% endif -%} 50 | 51 | } 52 | {% endfor -%} 53 | } 54 | {% endfor -%} 55 | } 56 | -------------------------------------------------------------------------------- /roles/interfaces/README.md: -------------------------------------------------------------------------------- 1 | # 'interfaces' role 2 | Generate configuration for production data plane interfaces. 3 | Currently supported os: vyos 4 | 5 | Features: 6 | - ethernet interface 7 | - vti interface 8 | 9 | ## Variables needed by the template 10 | 11 | ```yaml 12 | 13 | # eth0 interface is used at system role for mgmt purpose 14 | interfaces: 15 | # internal interface, type ethernet 16 | eth1: 17 | description: "internal" 18 | type: "ethernet" 19 | units: 20 | 0: 21 | family: 22 | inet: 23 | address: 24 | '10.0.0.20/22': 25 | 26 | # public interface, type ethernet 27 | eth2: 28 | description: "public" 29 | type: "ethernet" 30 | units: 31 | 0: 32 | family: 33 | inet: 34 | address: 35 | '5.5.5.5/27': 36 | 37 | # all configuration options 38 | eth3: 39 | description: "interface description" 40 | type: "ethernet" 41 | duplex: "full" 42 | speed: "100M" 43 | units: 44 | 0: 45 | # unit 0 has no auto vlan assign 46 | # use it for non tagged routed interfaces 47 | filter: 48 | input: "name for firewall filter" 49 | output: "name for firewall filter" 50 | family: 51 | inet: 52 | address: 53 | '1.1.1.2/24': 54 | vrrp_group: 55 | '1': 56 | virtual_address: "1.1.1.1" 57 | # optional default priority 100 58 | priority: "254" 59 | '2': 60 | virtual_address: "2.2.2.2" 61 | authentication: "yes" 62 | authentication_password: "some password" 63 | '2.2.2.2/24': 64 | 65 | # Tunnel interfaces VTI are used with ipsec configuration 66 | ipsec_vti: 67 | - iface: "vti0" 68 | local_ip: "169.254.44.194" 69 | remote_ip: "169.254.44.193" 70 | mask: "30" 71 | vti_test: "yes" 72 | 73 | ``` 74 | -------------------------------------------------------------------------------- /roles/interfaces/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from interface role" 3 | template: 4 | dest: "{{baseconfdir.path}}/60_interfaces.out" 5 | src: "{{os}}/interfaces.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/interfaces/templates/vyos/include/interfaces.j2: -------------------------------------------------------------------------------- 1 | {% macro vrrp_config(vrrp_group) %} 2 | vrrp { 3 | {% for group in vrrp_group -%} 4 | vrrp-group {{group}} { 5 | {% if vrrp_group[group].authentication is defined and vrrp_group[group].authentication == "true" and vrrp_group[group].authentication_password is defined -%} 6 | authentication { 7 | password {{vrrp_group[group].authentication_password}} 8 | type plaintext-password 9 | } 10 | {% endif %} 11 | {% if vrrp_group[group].preempt is defined and vrrp_group[group].preempt == "true" -%} 12 | preempt true 13 | preempt-delay {{vrrp_group[group].preempt_delay | default('30')}} 14 | {% else %} 15 | preempt false 16 | {% endif %} 17 | priority {{vrrp_group[group].priority | default('100')}} 18 | virtual-address {{vrrp_group[group].virtual_address}} 19 | {% if ipsec_peers is defined -%} 20 | run-transition-scripts { 21 | master /config/scripts/vyos_vrrp_transition_master.sh 22 | backup /config/scripts/vyos_vrrp_transition_master.sh 23 | } 24 | {% endif %} 25 | } 26 | {% endfor %} 27 | } 28 | {% endmacro %} 29 | {# 30 | 31 | #} 32 | {% macro filter_config(filter) %} 33 | firewall { 34 | {% if filter.input is defined -%} 35 | in { 36 | name {{ filter.input }} 37 | } 38 | {% endif -%} 39 | {% if filter.output is defined -%} 40 | out { 41 | name {{ filter.output }} 42 | } 43 | {% endif-%} 44 | {% if filter.local is defined -%} 45 | local { 46 | name {{ filter.local }} 47 | } 48 | {% endif-%} 49 | } 50 | {% endmacro %} 51 | 52 | interfaces { 53 | {% for intf in interfaces -%} 54 | {{ interfaces[intf].type }} {{ intf }} { 55 | {#interface address#} 56 | 57 | {% if interfaces[intf].units is defined -%} 58 | {% for unit in interfaces[intf].units -%} 59 | {% if not (unit==0) -%} 60 | vif {{unit}} { 61 | {% endif %} 62 | {% if interfaces[intf].units[unit].family['inet'] is defined -%} 63 | {% for address in interfaces[intf].units[unit].family['inet'].address -%} 64 | {% if True %} 65 | address {{address}} 66 | {% endif %} 67 | {% if interfaces[intf].units[unit].family['inet'].address[address].vrrp_group is defined -%} 68 | {{vrrp_config(interfaces[intf].units[unit].family['inet'].address[address].vrrp_group)}} 69 | {% endif %} 70 | {% endfor %} 71 | {% if interfaces[intf].units[unit].family['inet'].filter is defined -%} 72 | {{filter_config(interfaces[intf].units[unit].family['inet'].filter)}} 73 | {% endif %} 74 | {% endif %} 75 | {% if not (unit==0) -%} 76 | } 77 | {% endif %} 78 | {% endfor %} 79 | {% endif %} 80 | 81 | {% if interfaces[intf].description is defined -%} 82 | description {{ interfaces[intf].description }} 83 | {% endif %} 84 | {% if interfaces[intf].duplex is defined -%} 85 | duplex {{ interfaces[intf].duplex }} 86 | {% endif %} 87 | {% if interfaces[intf].duplex is defined -%} 88 | hw-id {{ interfaces[intf].hw_id }} 89 | {% endif %} 90 | {% if interfaces[intf].smp_affinity is defined -%} 91 | smp_affinity {{ interfaces[intf].smp_affinity }} 92 | {% endif %} 93 | {% if interfaces[intf].speed is defined -%} 94 | speed {{ interfaces[intf].speed }} 95 | {% endif %} 96 | {% if policy_mss_interface is defined -%} 97 | {% if policy_mss_interface == intf -%} 98 | policy { 99 | route mss 100 | } 101 | {% endif %} 102 | {% endif %} 103 | } 104 | {% endfor %} 105 | 106 | } 107 | -------------------------------------------------------------------------------- /roles/interfaces/templates/vyos/include/interfaces_vti.j2: -------------------------------------------------------------------------------- 1 | interfaces { 2 | {% for vti in ipsec_vti -%} 3 | vti {{vti.iface}} { 4 | address {{vti.local_ip}}/{{vti.mask}} 5 | mtu 1436 6 | } 7 | {% endfor -%} 8 | 9 | } 10 | -------------------------------------------------------------------------------- /roles/interfaces/templates/vyos/interfaces.j2: -------------------------------------------------------------------------------- 1 | {% if interfaces is defined %} 2 | {% include "include/interfaces.j2" %} 3 | {% endif %} 4 | 5 | {% if ipsec_vti is defined -%} 6 | {% include "include/interfaces_vti.j2" %} 7 | {% endif %} -------------------------------------------------------------------------------- /roles/ipsec/README.md: -------------------------------------------------------------------------------- 1 | # 'vrrp' role 2 | Generate ipsec configuration 3 | Currently supported os: vyos 4 | 5 | Features: 6 | - ipsec site-to-site 7 | 8 | ## Variables needed by the template vyos example 9 | 10 | ```yaml 11 | 12 | # role ipsec configuration values 13 | # role ipsec required Interface to use for VPN REQUIRED 14 | ipsec_interface: eth1 15 | # role ipsec optional (enable, disable) Network Address Translation (NAT) traversal 16 | ipsec_nat_traversal: enable 17 | 18 | # role ipsec Encapsulating Security Payload ESP groups 19 | ipsec_esp: 20 | - name: "AWS" 21 | compression: "disable" 22 | lifetime: "3600" 23 | mode: "tunnel" 24 | pfs: "enable" 25 | proposal: 26 | - { encryption: "aes128", hash: "sha1" } 27 | - name: "ESP-1W" 28 | lifetime: "28800" 29 | mode: "tunnel" 30 | pfs: "dh-group5" 31 | proposal: 32 | - { encryption: "3des", hash: "sha1" } 33 | - name: "ESP-1W-AES" 34 | lifetime: "28800" 35 | mode: "tunnel" 36 | pfs: "dh-group5" 37 | proposal: 38 | - { encryption: "aes256", hash: "sha1" } 39 | # role ipsec Name of Internet Key Exchange IKE groups 40 | ipsec_isakmp: 41 | - name: "AWS" 42 | dpd_config: 43 | - {dpd_action: "restart", dpd_interval: "15", dpd_timeout: "30" } 44 | ikev2_reauth: "no" 45 | key_exchange: "ikev1" 46 | lifetime: "28800" 47 | proposal: 48 | - { dh_group: "2", encryption: "aes128", hash: "sha1" } 49 | - name: "IKE-1W" 50 | lifetime: "86400" 51 | proposal: 52 | - { dh_group: "2", encryption: "3des", hash: "sha1" } 53 | - name: "IKE-1W-AES" 54 | lifetime: "86400" 55 | proposal: 56 | - { dh_group: "2", encryption: "3des", hash: "sha1" } 57 | # role ipsec Peers configuration. Required vti or tunnel config for a peer 58 | # role ipsec vti interface needs to be created 59 | ipsec_peers: 60 | - peerip: "192.168.56.12" 61 | # required description 62 | description: "to other vyos" 63 | # required currently only preshared is supported 64 | authentication_mode: "pre-shared-secret" 65 | autehntication_data: "123qwe" 66 | # required ike_group 67 | ike_group: "IKE-1W" 68 | # optional if address different than address on the ipsec interface 69 | # error if ip is eg network address for a subnet 70 | # local_address: "10.0.1.11" 71 | # optional default initiate, possible respond 72 | connection_type: "initiate" 73 | # optional ikev2-reauth yes, no, inherit 74 | ikev2_reauth: "inherit" 75 | # optional but we required it default-esp-group 76 | # without it each vti or tunnel will require this value 77 | default_esp_group: "ESP-1W" 78 | # required tunnel or vti do not configure both 79 | tunnels: 80 | # required local and remote prefix 81 | # optional esp_group 82 | - { local: "192.168.100.0/24", remote: "192.168.200.0/24", esp_group: "ESP-1W-AES" } 83 | 84 | 85 | ``` 86 | -------------------------------------------------------------------------------- /roles/ipsec/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from ipsec role" 3 | template: 4 | dest: "{{baseconfdir.path}}/50_ipsec.out" 5 | src: "{{os}}/ipsec.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/ipsec/templates/vyos/include/ipsec_peers.j2: -------------------------------------------------------------------------------- 1 | /* ipsec peers */ 2 | {# require additional ipaddr filter which comes in ansible 1.9 by default #} 3 | {% if ipsec_disable is defined %} 4 | {% else -%} 5 | 6 | vpn { 7 | ipsec { 8 | site-to-site { 9 | {% for ipsecpeer in ipsec_peers -%} 10 | peer {{ ipsecpeer.peerip }} { 11 | 12 | authentication { 13 | mode {{ ipsecpeer.authentication_mode }} 14 | pre-shared-secret {{ ipsecpeer.autehntication_data }} 15 | } 16 | description "{{ ipsecpeer.description }}" 17 | connection-type {{ ipsecpeer.connection_type | default('initiate') }} 18 | default-esp-group {{ ipsecpeer.default_esp_group }} 19 | ike-group {{ ipsecpeer.ike_group }} 20 | ikev2-reauth {{ ipsecpeer.ikev2_reauth }} 21 | 22 | {% if ipsecpeer.local_address is defined -%} 23 | local-address {{ ipsecpeer.local_address }} 24 | {% else -%} 25 | local-address {{ system_interfaces[ipsec_interface].address | ipaddr('address') }} 26 | {% endif %} 27 | 28 | {% if ipsecpeer.tunnels is defined -%} 29 | {% for tunnel in ipsecpeer.tunnels -%} 30 | tunnel {{ loop.index }} { 31 | allow-nat-networks {{ tunnel.allow_nat_networks | default('disable') }} 32 | allow-public-networks {{ tunnel.allow_public_networks | default('disable') }} 33 | esp-group {{ tunnel.esp_group | default(ipsecpeer.default_esp_group) }} 34 | local { 35 | prefix {{ tunnel.local }} 36 | } 37 | remote { 38 | prefix {{ tunnel.remote }} 39 | } 40 | } 41 | {% endfor -%} 42 | {% endif -%} 43 | 44 | {# todo vti tunnel type with creating interfaces in system #} 45 | {% if ipsecpeer.vti is defined -%} 46 | vti { 47 | bind {{ ipsecpeer.vti }} 48 | esp-group {{ ipsecpeer.default_esp_group }} 49 | } 50 | {% endif -%} 51 | } 52 | {% endfor -%} 53 | } 54 | } 55 | } 56 | 57 | {% endif %} 58 | -------------------------------------------------------------------------------- /roles/ipsec/templates/vyos/include/ipsec_settings.j2: -------------------------------------------------------------------------------- 1 | /* Ipsec settings */ 2 | {% if ipsec_disable is defined %} 3 | {% else -%} 4 | 5 | vpn { 6 | ipsec { 7 | 8 | {% for espcfg in ipsec_esp -%} 9 | esp-group {{ espcfg.name }} { 10 | {% if espcfg.compression is defined -%} 11 | compression {{ espcfg.compression }} 12 | {% endif -%} 13 | lifetime {{ espcfg.lifetime }} 14 | mode {{ espcfg.mode }} 15 | {% if espcfg.pfs is defined -%} 16 | pfs {{ espcfg.pfs }} 17 | {% endif -%} 18 | {% for espprop in espcfg.proposal -%} 19 | proposal {{ loop.index }} { 20 | encryption {{ espprop.encryption }} 21 | hash {{ espprop.hash }} 22 | } 23 | {% endfor -%} 24 | } 25 | {% endfor -%} 26 | 27 | 28 | 29 | 30 | {% for ikecfg in ipsec_isakmp -%} 31 | ike-group {{ ikecfg.name }} { 32 | {% if ikecfg.dpd_config is defined -%} 33 | dead-peer-detection { 34 | action {{ ikecfg.dpd_config[0].dpd_action }} 35 | interval {{ ikecfg.dpd_config[0].dpd_interval }} 36 | timeout {{ ikecfg.dpd_config[0].dpd_timeout }} 37 | } 38 | {% endif -%} 39 | {% if ikecfg.ikev2_reauth is defined -%} 40 | ikev2-reauth {{ ikecfg.ikev2_reauth }} 41 | {% endif -%} 42 | {% if ikecfg.key_exchange is defined -%} 43 | key-exchange {{ ikecfg.key_exchange }} 44 | {% endif -%} 45 | lifetime {{ ikecfg.lifetime }} 46 | {% for ikeprop in ikecfg.proposal -%} 47 | proposal {{ loop.index }} { 48 | dh-group {{ ikeprop.dh_group }} 49 | encryption {{ ikeprop.encryption }} 50 | hash {{ ikeprop.hash }} 51 | } 52 | {% endfor -%} 53 | } 54 | {% endfor -%} 55 | 56 | 57 | ipsec-interfaces { 58 | interface {{ ipsec_interface }} 59 | } 60 | 61 | {% if ipsec_nat_traversal is defined -%} 62 | nat-traversal {{ ipsec_nat_traversal }} 63 | {% endif -%} 64 | 65 | } 66 | } 67 | 68 | {% endif %} 69 | -------------------------------------------------------------------------------- /roles/ipsec/templates/vyos/ipsec.j2: -------------------------------------------------------------------------------- 1 | {% if ipsec_esp is defined or ipsec_isakmp is defined -%} 2 | {% include "include/ipsec_settings.j2" %} 3 | {% endif %} 4 | 5 | {% if ipsec_peers is defined -%} 6 | {% include "include/ipsec_peers.j2" %} 7 | {% endif %} 8 | -------------------------------------------------------------------------------- /roles/nat/README.md: -------------------------------------------------------------------------------- 1 | # 'vrrp' role 2 | Generate nat configuration 3 | Currently supported os: vyos 4 | 5 | Features: 6 | - source nat 7 | - destination nat 8 | 9 | ## Variables needed by the template vyos example 10 | 11 | ```yaml 12 | 13 | # role nat 14 | # nat vyos require: type (source, destination) 15 | 16 | # nat vyos source require: source_address, outbound_interface 17 | # translation_address (ip, range ip1-ip2, net/mask, masquerade) 18 | # optional: description 19 | nat_source_rules: 20 | - {description: "ru1", source_address: "192.168.200.0/24", 21 | outbound_interface: "eth2", translation_address: "172.16.3.1-172.16.3.100"} 22 | 23 | # nat vyos destination require: destination_address (ip, range ip1-ip2, ip/mask) 24 | # translation_address (ip, range ip1-ip2, ip/mask), inbound_interface 25 | # optional: description 26 | nat_destination_rules: 27 | - {description: "ru1", destination_address: "5.5.5.5/32", 28 | inbound_interface: "eth2", translation_address: "2.2.2.2/32"} 29 | 30 | 31 | ``` 32 | -------------------------------------------------------------------------------- /roles/nat/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from nat role" 3 | template: 4 | dest: "{{baseconfdir.path}}/40_nat.out" 5 | src: "{{os}}/nat.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/nat/templates/vyos/include/nat_destination_rules.j2: -------------------------------------------------------------------------------- 1 | nat { 2 | destination { 3 | {% for dstrule in nat_destination_rules -%} 4 | rule {{ loop.index }} { 5 | {% if dstrule.description is defined -%} 6 | description {{ dstrule.description }} 7 | {% endif %} 8 | destination { 9 | address {{ dstrule.destination_address }} 10 | } 11 | inbound-interface {{ dstrule.inbound_interface}} 12 | translation { 13 | address {{ dstrule.translation_address}} 14 | } 15 | } 16 | {% endfor -%} 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /roles/nat/templates/vyos/include/nat_source_rules.j2: -------------------------------------------------------------------------------- 1 | nat { 2 | source { 3 | {% for srcrule in nat_source_rules -%} 4 | rule {{ loop.index }} { 5 | {% if srcrule.description is defined -%} 6 | description {{ srcrule.description}} 7 | {% endif %} 8 | outbound-interface {{ srcrule.outbound_interface}} 9 | source { 10 | address {{ srcrule.source_address}} 11 | } 12 | translation { 13 | address {{ srcrule.translation_address}} 14 | } 15 | } 16 | {% endfor -%} 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /roles/nat/templates/vyos/nat.j2: -------------------------------------------------------------------------------- 1 | 2 | {% if nat_source_rules is defined -%} 3 | {% include "include/nat_source_rules.j2" %} 4 | {% endif %} 5 | 6 | {% if nat_destination_rules is defined -%} 7 | {% include "include/nat_destination_rules.j2" %} 8 | {% endif %} 9 | -------------------------------------------------------------------------------- /roles/policy/README.md: -------------------------------------------------------------------------------- 1 | # 'policy' role 2 | Generate policy configuration 3 | Currently supported os: vyos (only setting mtu) 4 | 5 | Features vyos: 6 | - prefix-list 7 | - policy statement (route-maps) 8 | - mtu 9 | 10 | ## Please split policies between group vars and host vars 11 | 12 | ```yaml 13 | 14 | # role policy vyos mss if required value, required interface 15 | # will not apply without values 16 | policy_mss_value: "1400" 17 | policy_mss_interface: "eth1" 18 | 19 | # role policy vyos prefix 20 | policy_prefix_list: 21 | "my-pfx-list": 22 | prefixes: 23 | - "1.2.2.3/32" 24 | "pfx-skype-controller": 25 | prefixes: 26 | - "5.45.181.254/32" 27 | 28 | # role policy vyos policy (route-map) 29 | policy_statement: 30 | "export-to-router": 31 | terms: 32 | - name: "match-some-net-1" 33 | from: 34 | prefix_list: "pl1" 35 | then: 36 | action: "accept" 37 | - name: "match-some-net-2" 38 | from: 39 | prefix_list: "pl2" 40 | then: 41 | action: "accept" 42 | metric: "50" 43 | - name: "match-some-net-3" 44 | from: 45 | prefix_list: "pl3" 46 | then: 47 | action: "accept" 48 | metric: "50" 49 | origin: "igp" 50 | 51 | ``` 52 | -------------------------------------------------------------------------------- /roles/policy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from policy role" 3 | template: 4 | dest: "{{baseconfdir.path}}/30_policy.out" 5 | src: "{{os}}/policy.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/policy/templates/vyos/include/policy_mss.j2: -------------------------------------------------------------------------------- 1 | policy { 2 | route mss { 3 | rule 5 { 4 | protocol tcp 5 | set { 6 | tcp-mss {{ policy_mss_value }} 7 | } 8 | tcp { 9 | flags SYN 10 | } 11 | } 12 | rule 10 { 13 | protocol tcp 14 | set { 15 | tcp-mss {{ policy_mss_value}} 16 | } 17 | tcp { 18 | flags SYN,RST 19 | } 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /roles/policy/templates/vyos/include/policy_prefix_list.j2: -------------------------------------------------------------------------------- 1 | policy { 2 | {% for pfx in policy_prefix_list -%} 3 | prefix-list {{ pfx }} { 4 | 5 | {% if policy_prefix_list[pfx].prefixes is defined -%} 6 | 7 | {% for prefix in policy_prefix_list[pfx].prefixes -%} 8 | {% set myloop = loop.index*10 %} 9 | rule {{myloop}} { 10 | action permit 11 | prefix {{prefix}} 12 | } 13 | {% endfor -%} 14 | {% endif -%} 15 | } 16 | {% endfor %} 17 | } 18 | -------------------------------------------------------------------------------- /roles/policy/templates/vyos/include/policy_statement.j2: -------------------------------------------------------------------------------- 1 | {% macro translate_action(action) %} 2 | {%- if action =='accept' %} 3 | permit 4 | {%- elif action =='reject' %} 5 | deny 6 | {%- else %} 7 | deny 8 | {% endif %} 9 | {% endmacro %} 10 | 11 | policy { 12 | {% for statement in policy_statement -%} 13 | route-map {{statement}} { 14 | {% for term in policy_statement[statement].terms -%} 15 | rule {{loop.index*10}} { 16 | action {{translate_action(term.then.action)}} 17 | {% if term.from is defined and term.from.prefix_list is defined -%} 18 | match { 19 | ip { 20 | address { 21 | prefix-list {{term.from.prefix_list}} 22 | } 23 | } 24 | } 25 | {% endif -%} 26 | 27 | {% if term.then is defined and (term.then.metric is defined or term.then.origin is defined)-%} 28 | set { 29 | metric {% if term.then.metric is defined %} {{term.then.metric}} {% endif %} 30 | 31 | origin {% if term.then.origin is defined %} {{term.then.origin}} {% endif %} 32 | 33 | } 34 | {% endif -%} 35 | } 36 | {% endfor -%} 37 | } 38 | 39 | {% endfor -%} 40 | } 41 | -------------------------------------------------------------------------------- /roles/policy/templates/vyos/policy.j2: -------------------------------------------------------------------------------- 1 | 2 | {% if policy_mss_value is defined and ( policy_mss_interface is defined) -%} 3 | {% include "include/policy_mss.j2" %} 4 | {% endif %} 5 | 6 | {% if policy_prefix_list is defined -%} 7 | {% include "include/policy_prefix_list.j2" %} 8 | {% endif %} 9 | 10 | {% if policy_statement is defined -%} 11 | {% include "include/policy_statement.j2" %} 12 | {% endif %} 13 | 14 | -------------------------------------------------------------------------------- /roles/protocols/README.md: -------------------------------------------------------------------------------- 1 | # 'protocols' role 2 | Generate protocols configuration 3 | Currently supported os: vyos 4 | 5 | Features: 6 | - protocol static 7 | 8 | ## Variables needed by the template vyos example 9 | 10 | ```yaml 11 | 12 | # role protocols 13 | # static routings if value exists require prefix and nextt hop (ip or discard) 14 | protocols_static: 15 | - {prefix: "192.168.0.0/16", 16 | next_hop: "{{system_interfaces['eth0'].gateway}}"} 17 | - {prefix: "10.0.0.0/8", next_hop: "{{system_interfaces['eth0'].gateway}}"} 18 | - {prefix: "0.0.0.0/0", next_hop: "discard"} 19 | 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /roles/protocols/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from protocols role" 3 | template: 4 | dest: "{{baseconfdir.path}}/20_protocols.out" 5 | src: "{{os}}/protocols.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/protocols/templates/vyos/include/protocols_static.j2: -------------------------------------------------------------------------------- 1 | protocols { 2 | static { 3 | {% for route in protocols_static -%} 4 | route {{route.prefix}} { 5 | next-hop {{route.next_hop}} { 6 | {% if route.distance is defined -%}distance {{route.distance}} 7 | {% endif -%} 8 | } 9 | } 10 | {% endfor %} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /roles/protocols/templates/vyos/protocols.j2: -------------------------------------------------------------------------------- 1 | 2 | {% if protocols_static is defined -%} 3 | {% include "include/protocols_static.j2" %} 4 | {% endif %} 5 | -------------------------------------------------------------------------------- /roles/system/README.md: -------------------------------------------------------------------------------- 1 | # 'system' role 2 | Generate basic system configuration 3 | Currently supported os: vyos 4 | 5 | Features: 6 | - accounts 7 | - banner 8 | - dhcp_relay 9 | - dns 10 | - hostname 11 | - interfaces 12 | - ntp 13 | - snmp 14 | - ssh 15 | - timezone 16 | 17 | ## Variables needed by the template vyos example 18 | 19 | ```yaml 20 | os: vyos 21 | 22 | # role system required 23 | system_hostname: "example_hostname" 24 | 25 | # role system optional default UTC 26 | system_timezone: "Europe/Warsaw" 27 | 28 | # role system required 29 | # password for user vyos is vyos 30 | system_accounts: 31 | - login: vyos 32 | encryptedpass: "$1$EckAeduc$dED6eP8sP/lSzWy33oezL." 33 | fullname: "Vyos account" 34 | uid: "2002" 35 | level: "admin" 36 | 37 | # role system optional 38 | system_banner: > 39 | PRODUCTION NETWORK UNAUTHORIZED USE OF THIS SYSTEM IS PROHIBITED! 40 | 41 | # system interfaces, type req in vyos 42 | system_interfaces: 43 | eth0: 44 | type: "ethernet" 45 | address: "10.0.0.10/24" 46 | gateway: "10.0.0.1" 47 | 48 | # role system service snmp 49 | # role system snmp required community 50 | # role system snmp optional contact, location 51 | system_snmp: 52 | contact: "a@b.com" 53 | location: "example location" 54 | communities: 55 | public: 56 | authorization: "ro" 57 | clients: 58 | - "1.1.1.1/32" 59 | - "2.2.2.2/32" 60 | 61 | # optional 62 | system_ntp: 63 | - {address: "213.222.193.35", prefer: "yes"} 64 | - {address: "193.219.28.149"} 65 | - {address: "195.187.245.55"} 66 | - {address: "217.17.34.82"} 67 | - {address: "149.156.4.11"} 68 | 69 | # role system ssh optional ip address 70 | system_ssh_listen: "10.0.2.15" 71 | # role system ssh optional int name 72 | # system_ssh_listen should be undefined 73 | system_ssh_listen_int: "eth1" 74 | 75 | # role system ssh optional, only keys 76 | system_ssh_diasble_pass_auth: "yes" 77 | 78 | # role system optional 79 | system_dns: 80 | - "1.1.1.1" 81 | - "8.8.8.8" 82 | 83 | # role system optional 84 | # remember to add inside and outside port for dhcp relay 85 | system_dhcp_relay_ports: "eth0 eth1" 86 | # system_dhcp_relay should point to dhcp server 87 | system_dhcp_relay: "1.1.1.1" 88 | 89 | ``` 90 | -------------------------------------------------------------------------------- /roles/system/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building configuration from system role" 3 | template: 4 | dest: "{{baseconfdir.path}}/10_system.out" 5 | src: "{{os}}/system.j2" 6 | tags: build 7 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_accounts.j2: -------------------------------------------------------------------------------- 1 | system { 2 | login { 3 | {% for user in system_accounts -%} 4 | user {{ user.login }} { 5 | authentication { 6 | {% if user.encryptedpass is defined -%} 7 | encrypted-password "{{ user.encryptedpass }}" 8 | {% endif -%} 9 | {% if user.plaintextpassword is defined -%} 10 | plaintext-password "{{ user.plaintextpassword }}" 11 | {% endif -%} 12 | 13 | {% if user.publickeys is defined -%} 14 | {% for keys in user.publickeys -%} 15 | public-keys {{ keys.keyname }} { 16 | key "{{ keys.key }}" 17 | type {{ keys.keytype }} 18 | } 19 | {% endfor -%} 20 | {% endif -%} 21 | } 22 | level admin 23 | } 24 | {% endfor -%} 25 | {% if system_additional_accounts is defined -%} 26 | {% for user in system_additional_accounts -%} 27 | user {{ user.login }} { 28 | authentication { 29 | {% if user.encryptedpass is defined -%} 30 | encrypted-password "{{ user.encryptedpass }}" 31 | {% endif -%} 32 | {% if user.plaintextpassword is defined -%} 33 | plaintext-password "{{ user.plaintextpassword }}" 34 | {% endif -%} 35 | 36 | {% if user.publickeys is defined -%} 37 | {% for keys in user.publickeys -%} 38 | public-keys {{ keys.keyname }} { 39 | key "{{ keys.key }}" 40 | type {{ keys.keytype }} 41 | } 42 | {% endfor -%} 43 | {% endif -%} 44 | } 45 | level admin 46 | } 47 | {% endfor -%} 48 | {% endif -%} 49 | } 50 | } -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_banner.j2: -------------------------------------------------------------------------------- 1 | system { 2 | login { 3 | banner { 4 | post-login "{{ system_banner }}" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_base.j2: -------------------------------------------------------------------------------- 1 | system { 2 | config-management { 3 | commit-revisions 20 4 | } 5 | host-name {{ system_hostname }} 6 | 7 | package { 8 | auto-sync 1 9 | repository community { 10 | components main 11 | distribution helium 12 | password "" 13 | url http://packages.vyos.net/vyos 14 | username "" 15 | } 16 | } 17 | 18 | time-zone {{system_timezone | default('UTC') }} 19 | } 20 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_dhcp_relay.j2: -------------------------------------------------------------------------------- 1 | service { 2 | dhcp-relay { 3 | {% for port in system_dhcp_relay_ports -%} 4 | interface {{port}} 5 | {% endfor-%} 6 | server {{system_dhcp_relay}} 7 | } 8 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_dns.j2: -------------------------------------------------------------------------------- 1 | 2 | system { 3 | {% for dnssrv in system_dns -%} 4 | name-server {{ dnssrv }} 5 | {% endfor -%} 6 | } 7 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_interfaces.j2: -------------------------------------------------------------------------------- 1 | 2 | interfaces { 3 | {% for intf in system_interfaces -%} 4 | {{ system_interfaces[intf].type }} {{ intf }} { 5 | address {{ system_interfaces[intf].address }} 6 | {% if system_interfaces[intf].description is defined -%} 7 | description {{ system_interfaces[intf].description }} 8 | {% endif -%} 9 | {% if system_interfaces[intf].duplex is defined -%} 10 | duplex {{ system_interfaces[intf].duplex }} 11 | {% endif -%} 12 | {% if system_interfaces[intf].duplex is defined -%} 13 | hw-id {{ system_interfaces[intf].hw_id }} 14 | {% endif -%} 15 | {% if system_interfaces[intf].smp_affinity is defined -%} 16 | smp_affinity {{ system_interfaces[intf].smp_affinity }} 17 | {% endif -%} 18 | {% if system_interfaces[intf].speed is defined -%} 19 | speed {{ system_interfaces[intf].speed }} 20 | {% endif -%} 21 | {% if firewall_interfaces is defined and ( firewall_rules is defined ) -%} 22 | {% if firewall_interfaces[intf] is defined %} 23 | firewall { 24 | {% if firewall_interfaces[intf].in is defined -%} 25 | in { 26 | name {{ firewall_interfaces[intf].in }} 27 | } 28 | {% endif -%} 29 | {% if firewall_interfaces[intf].out is defined -%} 30 | out { 31 | name {{ firewall_interfaces[intf].out}} 32 | } 33 | {% endif-%} 34 | } 35 | {% endif -%} 36 | {% endif -%} 37 | {% if policy_mss_interface is defined -%} 38 | {% if policy_mss_interface == intf -%} 39 | policy { 40 | route mss 41 | } 42 | {% endif -%} 43 | {% endif -%} 44 | } 45 | {% endfor -%} 46 | } 47 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_ntp.j2: -------------------------------------------------------------------------------- 1 | 2 | system { 3 | ntp { 4 | {% for ntpsrv in system_ntp -%} 5 | server {{ ntpsrv.address }} { 6 | } 7 | {% endfor -%} 8 | } 9 | } -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_snmp.j2: -------------------------------------------------------------------------------- 1 | 2 | service { 3 | snmp { 4 | 5 | {% if system_snmp.contact is defined -%} 6 | contact "{{system_snmp.contact}}" 7 | {% endif -%} 8 | {% if system_snmp.location is defined -%} 9 | location "{{system_snmp.location}}" 10 | {% endif -%} 11 | 12 | {% for community in system_snmp.communities -%} 13 | community {{community}} { 14 | authorization {{system_snmp.communities[community].authorization}} 15 | {% for client in system_snmp.communities[community].clients -%} 16 | client {{client}} 17 | {% endfor -%} 18 | } 19 | {% endfor -%} 20 | } 21 | } -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_ssh.j2: -------------------------------------------------------------------------------- 1 | service { 2 | ssh { 3 | disable-host-validation 4 | {% if system_ssh_diasble_pass_auth is defined -%} 5 | disable-password-authentication 6 | {% endif -%} 7 | {% if system_ssh_listen is defined -%} 8 | {% set sshaddr = system_ssh_listen | ipaddr('address') %} 9 | {% if sshaddr != False -%} 10 | listen-address {{ sshaddr }} 11 | {% endif -%} 12 | {% endif -%} 13 | 14 | {% if system_ssh_listen_int is defined and (not system_ssh_listen is defined)-%} 15 | {% set sshaddr = system_interfaces[system_ssh_listen_int].address | ipaddr('address') %} 16 | {% if sshaddr != False -%} 17 | listen-address {{ sshaddr }} 18 | {% endif -%} 19 | {% endif -%} 20 | 21 | port {{ system_ssh_port | default('22') }} 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/include/system_syslog.j2: -------------------------------------------------------------------------------- 1 | system { 2 | syslog { 3 | global { 4 | facility all { 5 | level notice 6 | } 7 | facility protocols { 8 | level debug 9 | } 10 | } 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/rc.local.j2: -------------------------------------------------------------------------------- 1 | # 2 | # rc.local 3 | # 4 | # This script is executed at the end of each multiuser runlevel. 5 | # value on error. 6 | # 7 | # In order to enable or disable this script just change the execution 8 | # bits. 9 | # 10 | # By default this script does nothing. 11 | ####################################### 12 | ## This file was copied by ansible # 13 | ## Please do not change it manually # 14 | ####################################### 15 | # Do not remove the following call to vyatta-postconfig-bootup.script. 16 | # Any boot time workarounds should be put in script below so that they 17 | # get preserved for the new image during image upgrade. 18 | POSTCONFIG=/opt/vyatta/etc/config/scripts/vyatta-postconfig-bootup.script 19 | [ -x $POSTCONFIG ] && $POSTCONFIG 20 | 21 | /sbin/ifconfig eth0 txqueuelen 16000 22 | /sbin/ifconfig eth1 txqueuelen 16000 23 | 24 | /sbin/ethtool -G eth0 rx 4096 25 | /sbin/ethtool -G eth1 rx 4096 26 | /sbin/ethtool -G eth0 tx 4096 27 | /sbin/ethtool -G eth1 tx 4096 28 | 29 | /usr/local/sbin/set_irq_affinity.sh eth0 30 | /usr/local/sbin/set_irq_affinity.sh eth1 31 | 32 | /sbin/ethtool -K eth0 tso off gro off gso off 33 | /sbin/ethtool -K eth1 tso off gro off gso off 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /roles/system/templates/vyos/system.j2: -------------------------------------------------------------------------------- 1 | /* Warning: Do not remove the following line. */ 2 | /* === vyatta-config-version: "cluster@1:config-management@1:conntrack-sync@1:conntrack@1:cron@1:dhcp-relay@1:dhcp-server@4:firewall@5:ipsec@4:nat@4:qos@1:quagga@2:system@6:vrrp@1:wanloadbalance@3:webgui@1:webproxy@1:zone-policy@1" === */ 3 | {% if vyos_frr_deamon is defined -%}} 4 | /* Release version: VyOS 1.2.0 */ 5 | {% elseif %} 6 | /* Release version: VyOS 1.1.8 */ 7 | {% endif %} 8 | 9 | {% include "include/system_base.j2" %} 10 | 11 | {% if system_ntp is defined %} 12 | {% include "include/system_ntp.j2" %} 13 | {% endif %} 14 | 15 | {% if system_dns is defined %} 16 | {% include "include/system_dns.j2" %} 17 | {% endif %} 18 | 19 | {% include "include/system_ssh.j2" %} 20 | 21 | {% if system_interfaces is defined %} 22 | {% include "include/system_interfaces.j2" %} 23 | {% endif %} 24 | 25 | {% include "include/system_syslog.j2" %} 26 | 27 | {% include "include/system_accounts.j2" %} 28 | 29 | {% if system_banner is defined %} 30 | {% include "include/system_banner.j2" %} 31 | {% endif %} 32 | 33 | 34 | {% if system_snmp is defined %} 35 | {% include "include/system_snmp.j2" %} 36 | {% endif %} 37 | 38 | 39 | {% if system_dhcp_relay is defined %} 40 | {% include "include/system_dhcp_relay.j2" %} 41 | {% endif %} 42 | --------------------------------------------------------------------------------