Compare commits
272 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5b7ea31ae | ||
|
|
f4a3730b0c | ||
|
|
6bcb10fa23 | ||
|
|
c024153b14 | ||
|
|
809dd15c52 | ||
|
|
319ade6951 | ||
|
|
71cc999073 | ||
|
|
d182801f7d | ||
|
|
3e5c7dbd00 | ||
|
|
c9cb720aff | ||
|
|
2e1c6c9c38 | ||
|
|
b7d597adfc | ||
|
|
9d10a51c9f | ||
|
|
1746378a62 | ||
|
|
d2002c292a | ||
|
|
13415c1702 | ||
|
|
ea88dec5fa | ||
|
|
ef4c3c70a1 | ||
|
|
9d72615c66 | ||
|
|
e71ea0c1b1 | ||
|
|
3f13ff4e6a | ||
|
|
e8e47c8429 | ||
|
|
74ab5f9222 | ||
|
|
07e746de23 | ||
|
|
580b6bdb0a | ||
|
|
5b0df293b9 | ||
|
|
08fce06943 | ||
|
|
caa6f8b9af | ||
|
|
7ce237ce1f | ||
|
|
aa63e6f08c | ||
|
|
67f126d84f | ||
|
|
0c8dc509d9 | ||
|
|
c43393e01c | ||
|
|
5da40d676a | ||
|
|
cab747169f | ||
|
|
d6bb8e0c06 | ||
|
|
3ed987e0f1 | ||
|
|
3c148d65ae | ||
|
|
0fef4f26f5 | ||
|
|
f1ef143ea4 | ||
|
|
42fe1f06e7 | ||
|
|
fd4b7ff7fc | ||
|
|
6a604b7beb | ||
|
|
dab2e1af9d | ||
|
|
4d29fbc73b | ||
|
|
8b85ad80c6 | ||
|
|
bba98c9f49 | ||
|
|
734c3d98f3 | ||
|
|
3076598865 | ||
|
|
f9eb141c15 | ||
|
|
83c11443ed | ||
|
|
f20289325a | ||
|
|
903df8ede4 | ||
|
|
5e3c350097 | ||
|
|
d57799a2f4 | ||
|
|
09e7c9ed0c | ||
|
|
d6019e8c51 | ||
|
|
39a997dd95 | ||
|
|
a60de82f58 | ||
|
|
2ceaae52ec | ||
|
|
aecbdb7bb3 | ||
|
|
5516a01b20 | ||
|
|
6b3edc69ff | ||
|
|
8e80443bca | ||
|
|
f97e0374fb | ||
|
|
320dee1ebe | ||
|
|
cc7f22069b | ||
|
|
d6a38952a4 | ||
|
|
87b75d3e7e | ||
|
|
59a7730e0e | ||
|
|
70648dfec9 | ||
|
|
d4d837d67e | ||
|
|
ae1e612783 | ||
|
|
be3e7f2777 | ||
|
|
022ecd9b04 | ||
|
|
281965e052 | ||
|
|
deb44d8856 | ||
|
|
79742d186a | ||
|
|
09be7abae1 | ||
|
|
df877ff5af | ||
|
|
735096b305 | ||
|
|
576234165e | ||
|
|
e0688e4297 | ||
|
|
3e64005907 | ||
|
|
9f115d1957 | ||
|
|
bba2a85660 | ||
|
|
1424e92cd6 | ||
|
|
62e8dbba0b | ||
|
|
12eea1750d | ||
|
|
b59b60745e | ||
|
|
b1461f62b9 | ||
|
|
af29c78e41 | ||
|
|
d2a3af453e | ||
|
|
58d8b562d2 | ||
|
|
9fe4b8a936 | ||
|
|
dd9c1a052f | ||
|
|
7fcf02c247 | ||
|
|
2723690178 | ||
|
|
67df648a49 | ||
|
|
4bc89c76b5 | ||
|
|
31b6b140e3 | ||
|
|
f9203543fc | ||
|
|
f84f075ffc | ||
|
|
6ae100b487 | ||
|
|
ffe3cfaf2f | ||
|
|
434ec318f0 | ||
|
|
737172ccd8 | ||
|
|
27970f7a20 | ||
|
|
b27069497d | ||
|
|
f78f351670 | ||
|
|
2f773ca216 | ||
|
|
e4931c26b2 | ||
|
|
45a9ed9668 | ||
|
|
d21e78c233 | ||
|
|
c4728f717b | ||
|
|
a10ae6117f | ||
|
|
8bb38d5112 | ||
|
|
6eca94082b | ||
|
|
d903bbc543 | ||
|
|
74996ba978 | ||
|
|
0be919e33b | ||
|
|
b41f22b4fb | ||
|
|
659a95161c | ||
|
|
95e86574b4 | ||
|
|
b6a9c6f94d | ||
|
|
0f413beec1 | ||
|
|
5a6aa7506d | ||
|
|
be722bf1bd | ||
|
|
7385cfe0d4 | ||
|
|
951c56bce1 | ||
|
|
26d5585bf8 | ||
|
|
507101862e | ||
|
|
0316ea57c6 | ||
|
|
fb9775d571 | ||
|
|
1586b040b9 | ||
|
|
7943e5513c | ||
|
|
3f854e2cb3 | ||
|
|
4263ff840a | ||
|
|
b31e243d9c | ||
|
|
762dba6581 | ||
|
|
e4d66ef8e3 | ||
|
|
73ac88e215 | ||
|
|
7952a12917 | ||
|
|
e30e9608d6 | ||
|
|
29d7b52c8e | ||
|
|
bb1abfb3fb | ||
|
|
ab4b43c2a2 | ||
|
|
859a9ee449 | ||
|
|
b0a96edc91 | ||
|
|
aa0c514ed0 | ||
|
|
fc61840372 | ||
|
|
204617bc29 | ||
|
|
d96b22b46f | ||
|
|
e72e6c6e3d | ||
|
|
1c0997cab9 | ||
|
|
7103937ac5 | ||
|
|
2ecaefa28b | ||
|
|
be81a4a967 | ||
|
|
8dac7b67ee | ||
|
|
a0c81044cf | ||
|
|
9e9216768f | ||
|
|
583988589f | ||
|
|
2ca41c150c | ||
|
|
0e9eb63365 | ||
|
|
3b08675325 | ||
|
|
1508a47a30 | ||
|
|
c54c051036 | ||
|
|
218c2bc974 | ||
|
|
d9b0403cab | ||
|
|
97dc32e5cd | ||
|
|
2772d9d89d | ||
|
|
5e13cabcbc | ||
|
|
f0a2ea8f8d | ||
|
|
093d35107e | ||
|
|
95518d579e | ||
|
|
c07b6d69f1 | ||
|
|
6c68854aae | ||
|
|
6f9d52dcb3 | ||
|
|
5d8be0756e | ||
|
|
e2d80596eb | ||
|
|
7d34dafb63 | ||
|
|
7b23beeb3c | ||
|
|
3c6bb1ec30 | ||
|
|
5447c0509f | ||
|
|
f995bfe32c | ||
|
|
227125a387 | ||
|
|
dbb2613024 | ||
|
|
0b6608b1a6 | ||
|
|
b73c97e995 | ||
|
|
244e576b3d | ||
|
|
6ed85600b2 | ||
|
|
3d927aa7ee | ||
|
|
84b4a10bbe | ||
|
|
5eeeb7bb5f | ||
|
|
9ad99d5e91 | ||
|
|
cf6712773d | ||
|
|
67ec752354 | ||
|
|
9215c31e3c | ||
|
|
bcef0f76c5 | ||
|
|
a45a98349c | ||
|
|
083522b2ec | ||
|
|
fad5623e87 | ||
|
|
1431c3736b | ||
|
|
80e696c186 | ||
|
|
02446eb692 | ||
|
|
03f0cff457 | ||
|
|
8a81c9ccfb | ||
|
|
f5bdaf8309 | ||
|
|
98e93c7c6f | ||
|
|
1e0eda1e57 | ||
|
|
81a1d1910b | ||
|
|
f4c1c78c25 | ||
|
|
c56a395d74 | ||
|
|
ca8b793cff | ||
|
|
3dd4dd917b | ||
|
|
978261e479 | ||
|
|
d7e54b8d8f | ||
|
|
930a7f5cca | ||
|
|
00b149998c | ||
|
|
38694b4738 | ||
|
|
c72e0d8f9a | ||
|
|
ffcd662442 | ||
|
|
4d5a41412d | ||
|
|
20a6836e16 | ||
|
|
96f865899e | ||
|
|
4b14c6c749 | ||
|
|
97a3df1722 | ||
|
|
0036cdf291 | ||
|
|
e22e1586d8 | ||
|
|
6414b4db09 | ||
|
|
e5571ffdbf | ||
|
|
c8805cba13 | ||
|
|
8c1ba05b68 | ||
|
|
81a5c9cddb | ||
|
|
b3afd820d8 | ||
|
|
6ad3e46ff2 | ||
|
|
6f1ed9681b | ||
|
|
689d38c812 | ||
|
|
0a5103984a | ||
|
|
df008237c5 | ||
|
|
6e4faf0188 | ||
|
|
751455caca | ||
|
|
4fc7bdf5db | ||
|
|
a141b96427 | ||
|
|
9d29475d9f | ||
|
|
09a8acd602 | ||
|
|
8a11b8b129 | ||
|
|
9bfe2ec7e9 | ||
|
|
690647a1df | ||
|
|
a9f2c27c38 | ||
|
|
84498945cc | ||
|
|
5dff955e49 | ||
|
|
9c961c0d52 | ||
|
|
5fb241c9ae | ||
|
|
d6d9dbbbef | ||
|
|
4aa0865d9f | ||
|
|
32400cbbda | ||
|
|
841cf147ec | ||
|
|
2c61e8fa88 | ||
|
|
2e905f826e | ||
|
|
34fb6eba8b | ||
|
|
21f0d774b5 | ||
|
|
d0c971118c | ||
|
|
a98dc001a8 | ||
|
|
beb1af052e | ||
|
|
c2b5fd2486 | ||
|
|
fa995c7dcb | ||
|
|
0834ca58cd | ||
|
|
92d4956d53 | ||
|
|
1a01a619ab | ||
|
|
273265f02b | ||
|
|
babdb42a27 |
3
.github/reviewers.yml
vendored
@ -1,3 +0,0 @@
|
||||
---
|
||||
'**/*':
|
||||
- rebortg
|
||||
177
.github/vyos-linter.py
vendored
@ -1,177 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import ipaddress
|
||||
import sys
|
||||
import ast
|
||||
|
||||
IPV4SEG = r'(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])'
|
||||
IPV4ADDR = r'\b(?:(?:' + IPV4SEG + r'\.){3,3}' + IPV4SEG + r')\b'
|
||||
IPV6SEG = r'(?:(?:[0-9a-fA-F]){1,4})'
|
||||
IPV6GROUPS = (
|
||||
r'(?:' + IPV6SEG + r':){7,7}' + IPV6SEG, # 1:2:3:4:5:6:7:8
|
||||
r'(?:\s' + IPV6SEG + r':){1,7}:', # 1:: 1:2:3:4:5:6:7::
|
||||
r'(?:' + IPV6SEG + r':){1,6}:' + IPV6SEG, # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
r'(?:' + IPV6SEG + r':){1,5}(?::' + IPV6SEG + r'){1,2}', # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
r'(?:' + IPV6SEG + r':){1,4}(?::' + IPV6SEG + r'){1,3}', # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
r'(?:' + IPV6SEG + r':){1,3}(?::' + IPV6SEG + r'){1,4}', # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
r'(?:' + IPV6SEG + r':){1,2}(?::' + IPV6SEG + r'){1,5}', # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
IPV6SEG + r':(?:(?::' + IPV6SEG + r'){1,6})', # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
r':(?:(?::' + IPV6SEG + r'){1,7}|:)', # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
r'fe80:(?::' + IPV6SEG + r'){0,4}%[0-9a-zA-Z]{1,}', # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
r'::(?:ffff(?::0{1,4}){0,1}:){0,1}[^\s:]' + IPV4ADDR, # ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
r'(?:' + IPV6SEG + r':){1,4}:[^\s:]' + IPV4ADDR, # 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
|
||||
)
|
||||
IPV6ADDR = '|'.join(['(?:{})'.format(g) for g in IPV6GROUPS[::-1]]) # Reverse rows for greedy match
|
||||
|
||||
MAC = r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
|
||||
|
||||
NUMBER = r"([\s']\d+[\s'])"
|
||||
|
||||
|
||||
def lint_mac(cnt, line):
|
||||
mac = re.search(MAC, line, re.I)
|
||||
if mac is not None:
|
||||
mac = mac.group()
|
||||
u_mac = re.search(r'((00)[:-](53)([:-][0-9A-F]{2}){4})', mac, re.I)
|
||||
m_mac = re.search(r'((90)[:-](10)([:-][0-9A-F]{2}){4})', mac, re.I)
|
||||
if u_mac is None and m_mac is None:
|
||||
return (f"Use MAC reserved for Documentation (RFC7042): {mac}", cnt, 'error')
|
||||
|
||||
|
||||
def lint_ipv4(cnt, line):
|
||||
ip = re.search(IPV4ADDR, line, re.I)
|
||||
if ip is not None:
|
||||
ip = ipaddress.ip_address(ip.group().strip(' '))
|
||||
# https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_private
|
||||
if ip.is_private:
|
||||
return None
|
||||
if ip.is_multicast:
|
||||
return None
|
||||
if ip.is_global is False:
|
||||
return None
|
||||
return (f"Use IPv4 reserved for Documentation (RFC 5737) or private Space: {ip}", cnt, 'error')
|
||||
|
||||
|
||||
def lint_ipv6(cnt, line):
|
||||
ip = re.search(IPV6ADDR, line, re.I)
|
||||
if ip is not None:
|
||||
ip = ipaddress.ip_address(ip.group().strip(' '))
|
||||
if ip.is_private:
|
||||
return None
|
||||
if ip.is_multicast:
|
||||
return None
|
||||
if ip.is_global is False:
|
||||
return None
|
||||
return (f"Use IPv6 reserved for Documentation (RFC 3849) or private Space: {ip}", cnt, 'error')
|
||||
|
||||
|
||||
def lint_AS(cnt, line):
|
||||
number = re.search(NUMBER, line, re.I)
|
||||
if number:
|
||||
pass
|
||||
# find a way to detect AS numbers
|
||||
|
||||
|
||||
def lint_linelen(cnt, line):
|
||||
line = line.rstrip()
|
||||
if len(line) > 80:
|
||||
return (f"Line too long: len={len(line)}", cnt, 'warning')
|
||||
|
||||
def handle_file_action(filepath):
|
||||
errors = []
|
||||
try:
|
||||
with open(filepath) as fp:
|
||||
line = fp.readline()
|
||||
cnt = 1
|
||||
test_line_lenght = True
|
||||
start_vyoslinter = True
|
||||
indentation = 0
|
||||
while line:
|
||||
# search for ignore linter comments in lines
|
||||
if ".. stop_vyoslinter" in line:
|
||||
start_vyoslinter = False
|
||||
if ".. start_vyoslinter" in line:
|
||||
start_vyoslinter = True
|
||||
if start_vyoslinter:
|
||||
# ignore every '.. code-block::' for line lenght
|
||||
# rst code-block have its own style in html the format in rst
|
||||
# and the build page must be the same
|
||||
if test_line_lenght is False:
|
||||
if len(line) > indentation:
|
||||
#print(f"'{line}'")
|
||||
#print(indentation)
|
||||
if line[indentation].isspace() is False:
|
||||
test_line_lenght = True
|
||||
|
||||
if ".. code-block::" in line:
|
||||
test_line_lenght = False
|
||||
indentation = 0
|
||||
for i in line:
|
||||
if i.isspace():
|
||||
indentation = indentation + 1
|
||||
else:
|
||||
break
|
||||
|
||||
err_mac = lint_mac(cnt, line.strip())
|
||||
# disable mac detection for the moment, too many false positives
|
||||
err_mac = None
|
||||
err_ip4 = lint_ipv4(cnt, line.strip())
|
||||
err_ip6 = lint_ipv6(cnt, line.strip())
|
||||
if test_line_lenght:
|
||||
err_len = lint_linelen(cnt, line)
|
||||
else:
|
||||
err_len = None
|
||||
if err_mac:
|
||||
errors.append(err_mac)
|
||||
if err_ip4:
|
||||
errors.append(err_ip4)
|
||||
if err_ip6:
|
||||
errors.append(err_ip6)
|
||||
if err_len:
|
||||
errors.append(err_len)
|
||||
|
||||
line = fp.readline()
|
||||
cnt += 1
|
||||
|
||||
# ensure linter was not stop on top and forgot to tun on again
|
||||
if start_vyoslinter == False:
|
||||
errors.append((f"Don't forgett to turn linter back on", cnt, 'error'))
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
if len(errors) > 0:
|
||||
'''
|
||||
"::{$type} file={$filename},line={$line},col=$column::{$log}"
|
||||
'''
|
||||
print(f"File: {filepath}")
|
||||
for error in errors:
|
||||
print(f"::{error[2]} file={filepath},line={error[1]}::{error[0]}")
|
||||
print('')
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
bool_error = True
|
||||
print('start')
|
||||
try:
|
||||
files = ast.literal_eval(sys.argv[1])
|
||||
for file in files:
|
||||
if file[-4:] in [".rst", ".txt"] and "_build" not in file:
|
||||
if handle_file_action(file) is False:
|
||||
bool_error = False
|
||||
except Exception as e:
|
||||
for root, dirs, files in os.walk("docs"):
|
||||
path = root.split(os.sep)
|
||||
for file in files:
|
||||
if file[-4:] in [".rst", ".txt"] and "_build" not in path:
|
||||
fpath = '/'.join(path)
|
||||
filepath = f"{fpath}/{file}"
|
||||
if handle_file_action(filepath) is False:
|
||||
bool_error = False
|
||||
|
||||
return bool_error
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if main() == False:
|
||||
exit(1)
|
||||
21
.github/workflows/auto-author-assign.yml
vendored
@ -3,25 +3,12 @@ on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, ready_for_review, locked]
|
||||
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
# https://github.com/marketplace/actions/auto-author-assign
|
||||
assign-author:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Assign Author to PR"
|
||||
uses: toshimaru/auto-author-assign@v1.3.5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# https://github.com/shufo/auto-assign-reviewer-by-files
|
||||
assign_reviewer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Request review based on files changes and/or groups the author belongs to
|
||||
uses: shufo/auto-assign-reviewer-by-files@v1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
config: .github/reviewers.yml
|
||||
uses: vyos/.github/.github/workflows/assign-author.yml@feature/T6349-reusable-workflows
|
||||
secrets: inherit
|
||||
|
||||
14
.github/workflows/check-pr-conflicts.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
name: "PR Conflicts checker"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-pr-conflict-call:
|
||||
uses: vyos/.github/.github/workflows/check-pr-merge-conflict.yml@feature/T6349-reusable-workflows
|
||||
secrets: inherit
|
||||
10
.github/workflows/lint-doc.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
name: Lint Doc
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint-doc:
|
||||
uses: vyos/.github/.github/workflows/lint-doc.yml@feature/T6349-reusable-workflows
|
||||
secrets: inherit
|
||||
|
||||
|
||||
27
.github/workflows/main.yml
vendored
@ -1,27 +0,0 @@
|
||||
name: Linting
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: File Changes
|
||||
id: file_changes
|
||||
uses: trilom/file-changes-action@v1.2.3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: run python based linter
|
||||
run: python .github/vyos-linter.py '${{ steps.file_changes.outputs.files_modified }}'
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
|
||||
19
.github/workflows/pr-conflicts.yml
vendored
@ -1,19 +0,0 @@
|
||||
name: "PR Conflicts checker"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
Conflict_Check:
|
||||
name: 'Check PR status: conflicts and resolution'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: check if PRs are dirty
|
||||
uses: eps1lon/actions-label-merge-conflict@releases/2.x
|
||||
with:
|
||||
dirtyLabel: "state: conflict"
|
||||
removeOnDirtyLabel: "state: conflict resolved"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This pull request has conflicts, please resolve those before we can evaluate the pull request."
|
||||
commentOnClean: "Conflicts have been resolved. A maintainer will review the pull request shortly."
|
||||
|
||||
1
.gitignore
vendored
@ -7,6 +7,7 @@ venv/
|
||||
ENV/
|
||||
.venv
|
||||
Pipfile.lock
|
||||
Pipfile
|
||||
|
||||
# put various editor ignores here
|
||||
.vscode/
|
||||
|
||||
@ -18,8 +18,8 @@ sphinx:
|
||||
# configuration: mkdocs.yml
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF
|
||||
#formats:
|
||||
# - pdf
|
||||
formats:
|
||||
- pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
|
||||
2
CODEOWNERS
Normal file
@ -0,0 +1,2 @@
|
||||
* @vyos/reviewers
|
||||
* @rebortg
|
||||
18
README.md
@ -90,12 +90,14 @@ If the `vyos/vyos-documentation` container could not be found locally it will be
|
||||
automatically fetched from Dockerhub.
|
||||
|
||||
```bash
|
||||
$ docker run --rm -it -v "$(pwd)":/vyos -w /vyos/docs \
|
||||
-e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation make html
|
||||
$ git clone https://github.com/vyos/vyos-documentation.git
|
||||
|
||||
# sphinx autobuild
|
||||
$ docker run --rm -it -p 8000:8000 -v "$(pwd)":/vyos -w /vyos/docs -e \
|
||||
GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation make livehtml
|
||||
$ cd vyos-documentation
|
||||
|
||||
$ docker run --rm -it -v "$(pwd)":/vyos -w /vyos/docs -e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation make html
|
||||
|
||||
# For sphinx autobuild
|
||||
$ docker run --rm -it -p 8000:8000 -v "$(pwd)":/vyos -w /vyos/docs -e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation make livehtml
|
||||
```
|
||||
|
||||
### Test the docs
|
||||
@ -103,13 +105,11 @@ $ docker run --rm -it -p 8000:8000 -v "$(pwd)":/vyos -w /vyos/docs -e \
|
||||
To test all files, run:
|
||||
|
||||
```bash
|
||||
$ docker run --rm -it -v "$(pwd)":/vyos -w /vyos/docs \
|
||||
-e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation vale .
|
||||
$ docker run --rm -it -v "$(pwd)":/vyos -w /vyos/docs -e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation vale .
|
||||
```
|
||||
|
||||
to test a specific file (e.g. `quick-start.rst`)
|
||||
|
||||
```bash
|
||||
$ docker run --rm -it -v "$(pwd)":/vyos -w /vyos/docs -e GOSU_UID=$(id -u) \
|
||||
-e GOSU_GID=$(id -g) vyos/vyos-documentation vale quick-start.rst
|
||||
$ docker run --rm -it -v "$(pwd)":/vyos -w /vyos/docs -e GOSU_UID=$(id -u) -e GOSU_GID=$(id -g) vyos/vyos-documentation vale quick-start.rst
|
||||
```
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Must be run with --privileged flag
|
||||
# Recommended to run the container with a volume mapped
|
||||
# in order to easy exprort images built to "external" world
|
||||
FROM debian:11
|
||||
FROM debian:12
|
||||
LABEL authors="VyOS Maintainers <maintainers@vyos.io>"
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
@ -27,16 +27,14 @@ RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
dos2unix
|
||||
|
||||
|
||||
|
||||
RUN pip3 install Sphinx
|
||||
RUN pip3 install sphinx-rtd-theme
|
||||
RUN pip3 install sphinx-autobuild
|
||||
RUN pip3 install sphinx-notfound-page
|
||||
RUN pip3 install lxml
|
||||
RUN pip3 install myst-parser
|
||||
RUN pip3 install sphinx-panels
|
||||
|
||||
RUN pip3 install --break-system-packages \
|
||||
Sphinx \
|
||||
sphinx-rtd-theme \
|
||||
sphinx-autobuild \
|
||||
sphinx-notfound-page \
|
||||
lxml \
|
||||
myst-parser \
|
||||
sphinx_design
|
||||
|
||||
# Cleanup
|
||||
RUN rm -rf /var/lib/apt/lists/*
|
||||
@ -44,13 +42,11 @@ RUN rm -rf /var/lib/apt/lists/*
|
||||
EXPOSE 8000
|
||||
|
||||
# Allow password-less 'sudo' for all users in group 'sudo'
|
||||
RUN sed "s/^%sudo.*/%sudo\tALL=(ALL) NOPASSWD:ALL/g" -i /etc/sudoers && \
|
||||
chmod a+s /usr/sbin/useradd /usr/sbin/groupadd /usr/sbin/gosu /usr/sbin/usermod
|
||||
|
||||
RUN sed "s/^%sudo.*/%sudo\tALL=(ALL) NOPASSWD:ALL/g" -i /etc/sudoers
|
||||
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
|
||||
# we need to convert the entrypoint with appropriate line endings, else
|
||||
# We need to convert the entrypoint with appropriate line endings, else
|
||||
# there will be an error:
|
||||
# standard_init_linux.go:175: exec user process caused
|
||||
# "no such file or directory"
|
||||
|
||||
@ -23,10 +23,10 @@ if ! grep -q $NEW_GID /etc/group; then
|
||||
groupadd --gid $NEW_GID $USER_NAME
|
||||
fi
|
||||
|
||||
useradd --shell /bin/bash --uid $NEW_UID --gid $NEW_GID --non-unique --create-home $USER_NAME
|
||||
useradd --shell /bin/bash --uid $NEW_UID --gid $NEW_GID --non-unique --create-home $USER_NAME --key UID_MIN=500
|
||||
usermod --append --groups sudo $USER_NAME
|
||||
sudo chown $NEW_UID:$NEW_GID /home/$USER_NAME
|
||||
chown $NEW_UID:$NEW_GID /home/$USER_NAME
|
||||
export HOME=/home/$USER_NAME
|
||||
|
||||
# Execute process
|
||||
exec /usr/sbin/gosu $USER_NAME "$@"
|
||||
/usr/sbin/gosu $USER_NAME "$@"
|
||||
|
||||
@ -8,4 +8,5 @@ Try using the search box or go to the release homepage:
|
||||
|
||||
* `1.2.x (crux) <https://docs.vyos.io/en/crux/>`_
|
||||
* `1.3.x (equuleus) <https://docs.vyos.io/en/equuleus/>`_
|
||||
* `rolling release (sagitta) <https://docs.vyos.io/en/latest/>`_
|
||||
* `1.4.x (sagitta) <https://docs.vyos.io/en/sagitta/>`_
|
||||
* `rolling release (circinus) <https://docs.vyos.io/en/latest/>`_
|
||||
|
||||
@ -530,7 +530,7 @@ def strip_cmd(cmd, debug=False):
|
||||
if c == "]":
|
||||
appearance = appearance - 1
|
||||
|
||||
# only if all [..] will be delete if appearance > 0 there is a syntax errror
|
||||
# only if all [..] will be delete if appearance > 0 there is a syntax error
|
||||
if appearance == 0:
|
||||
cmd = cmd_new
|
||||
|
||||
@ -545,7 +545,7 @@ def strip_cmd(cmd, debug=False):
|
||||
if c == ">":
|
||||
appearance = appearance - 1
|
||||
|
||||
# only if all <..> will be delete if appearance > 0 there is a syntax errror
|
||||
# only if all <..> will be delete if appearance > 0 there is a syntax error
|
||||
if appearance == 0:
|
||||
cmd = cmd_new
|
||||
|
||||
|
||||
11
docs/_include/interface-evpn-uplink.txt
Normal file
@ -0,0 +1,11 @@
|
||||
.. cfgcmd:: set interfaces {{ var0 }} <interface> evpn uplink
|
||||
|
||||
When all the underlay links go down the PE no longer has access
|
||||
to the VxLAN +overlay. To prevent blackholing of traffic the
|
||||
server/ES links are protodowned on the PE.
|
||||
|
||||
A link can be setup for uplink tracking via the following example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set interfaces {{ var0 }} {{ var1 }} evpn uplink
|
||||
@ -1 +1 @@
|
||||
Subproject commit 3d9a0b02d031a97b099ef6fe4ba07d7ce7eb958e
|
||||
Subproject commit f980f8b8010a9681c387d47c476254c89b0c4a25
|
||||
@ -12421,8 +12421,8 @@ msgid "Sometimes option lines in the generated OpenVPN configuration require quo
|
||||
msgstr "Sometimes option lines in the generated OpenVPN configuration require quotes. This is done through a hack on our config generator. You can pass quotes using the ``"`` statement."
|
||||
|
||||
#: ../../configuration/service/dhcp-server.rst:771
|
||||
msgid "Sort the output by the specified key. Possible keys: expires, iaid_duid, ip, last_comm, pool, remaining, state, type (default = ip)"
|
||||
msgstr "Sort the output by the specified key. Possible keys: expires, iaid_duid, ip, last_comm, pool, remaining, state, type (default = ip)"
|
||||
msgid "Sort the output by the specified key. Possible keys: expires, duid, ip, last_comm, pool, remaining, state, type (default = ip)"
|
||||
msgstr "Sort the output by the specified key. Possible keys: expires, duid, ip, last_comm, pool, remaining, state, type (default = ip)"
|
||||
|
||||
#: ../../configuration/service/dhcp-server.rst:566
|
||||
msgid "Sort the output by the specified key. Possible keys: ip, hardware_address, state, start, end, remaining, pool, hostname (default = ip)"
|
||||
@ -13647,8 +13647,8 @@ msgid "The hostname or IP address of the master"
|
||||
msgstr "The hostname or IP address of the master"
|
||||
|
||||
#: ../../configuration/service/dhcp-server.rst:700
|
||||
msgid "The identifier is the device's DUID: colon-separated hex list (as used by isc-dhcp option dhcpv6.client-id). If the device already has a dynamic lease from the DHCPv6 server, its DUID can be found with ``show service dhcpv6 server leases``. The DUID begins at the 5th octet (after the 4th colon) of IAID_DUID."
|
||||
msgstr "The identifier is the device's DUID: colon-separated hex list (as used by isc-dhcp option dhcpv6.client-id). If the device already has a dynamic lease from the DHCPv6 server, its DUID can be found with ``show service dhcpv6 server leases``. The DUID begins at the 5th octet (after the 4th colon) of IAID_DUID."
|
||||
msgid "The identifier is the device's DUID: colon-separated hex list (as used by isc-dhcp option dhcpv6.client-id). If the device already has a dynamic lease from the DHCPv6 server, its DUID can be found with ``show service dhcpv6 server leases``."
|
||||
msgstr "The identifier is the device's DUID: colon-separated hex list (as used by isc-dhcp option dhcpv6.client-id). If the device already has a dynamic lease from the DHCPv6 server, its DUID can be found with ``show service dhcpv6 server leases``."
|
||||
|
||||
#: ../../configuration/vpn/dmvpn.rst:237
|
||||
msgid "The individual spoke configurations only differ in the local IP address on the ``tun10`` interface. See the above diagram for the individual IP addresses."
|
||||
|
||||
165
docs/_static/css/breadcrumbs.css
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
.wy-breadcrumbs {
|
||||
|
||||
& > li,
|
||||
& > li a {
|
||||
color: #636A6D;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.5px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
& > li a {
|
||||
padding: 0 5px 0 0;
|
||||
}
|
||||
|
||||
& > li:nth-child(1) {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
& > li > .icon-home::after {
|
||||
content: url('../images/breadcrumbs-icon.svg');
|
||||
visibility: visible;
|
||||
top: 6px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
& > li > .icon-home::before {
|
||||
padding-right: 0;
|
||||
content: 'Home';
|
||||
visibility: visible;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
letter-spacing: -0.5px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
& > li:nth-child(n + 1) {
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
& > li:nth-child(n + 1)::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& > li:nth-last-child(2) {
|
||||
color: #121010;
|
||||
}
|
||||
|
||||
& > li:nth-last-child(2)::after,
|
||||
& > li:nth-last-child(1)::after {
|
||||
display: none !important
|
||||
}
|
||||
|
||||
& > li:nth-child(n + 1)::after {
|
||||
content: url('../images/breadcrumbs-icon.svg');
|
||||
top: 0;
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
& > li:last-of-type:has(a),
|
||||
& > li:last-of-type:has(a) a {
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
color: #fff;
|
||||
background-color: #121010;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
& > li:last-of-type:has(a) {
|
||||
padding: 7px 10px;
|
||||
border-radius: 4px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
& > li:last-of-type:has(a) a {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
& > li:last-of-type:has(a) a::before {
|
||||
content: url('../images/github.svg');
|
||||
margin-right: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
& > li:last-of-type::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 375px) {
|
||||
|
||||
.wy-breadcrumbs {
|
||||
& > li > .icon-home::after {
|
||||
right: -2px;
|
||||
}
|
||||
|
||||
& > li:nth-child(n + 1)::after {
|
||||
right: -13px;
|
||||
}
|
||||
}
|
||||
|
||||
.wy-breadcrumbs > li {
|
||||
padding: 5px 5px 5px 0;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs > li,
|
||||
.wy-breadcrumbs > li a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs > li > .icon-home::before {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 376px) {
|
||||
.wy-breadcrumbs {
|
||||
& > li > .icon-home::after {
|
||||
right: -8px;
|
||||
}
|
||||
|
||||
& > li:nth-child(n + 1)::after {
|
||||
right: -13px;
|
||||
}
|
||||
}
|
||||
|
||||
.wy-breadcrumbs > li {
|
||||
padding: 5px 5px 5px 10px;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs > li,
|
||||
.wy-breadcrumbs > li a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.wy-breadcrumbs > li > .icon-home::before {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 991px) {
|
||||
li.wy-breadcrumbs-aside {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
ul.wy-breadcrumbs:has(li + li + li + li) li.wy-breadcrumbs-aside {
|
||||
margin: 24px 0 16px;
|
||||
max-width: 140px;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
233
docs/_static/css/code-snippets.css
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
.rst-content {
|
||||
& div[class^=highlight],
|
||||
& pre.literal-block {
|
||||
border: none;
|
||||
background: linear-gradient(#FF9000, #FFBF12);
|
||||
border-radius: 8px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
& div[class^=highlight] div[class^=highlight],
|
||||
& pre.literal-block div[class^=highlight] {
|
||||
background: #525659 !important;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
& .linenodiv pre,
|
||||
& div[class^=highlight] pre,
|
||||
& pre.literal-block {
|
||||
font-size: 16px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.04em;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
overflow-x: scroll;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
& .linenodiv pre::-webkit-scrollbar,
|
||||
& div[class^=highlight] pre::-webkit-scrollbar,
|
||||
& pre.literal-block::-webkit-scrollbar {
|
||||
height: 3px;
|
||||
color: #99A0A5 transparent;
|
||||
}
|
||||
|
||||
& .linenodiv pre::-webkit-scrollbar-track,
|
||||
& div[class^=highlight] pre::-webkit-scrollbar-track,
|
||||
& pre.literal-block::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
border-radius: 8px;
|
||||
margin: 0 18px;
|
||||
}
|
||||
|
||||
& .linenodiv pre::-webkit-scrollbar-thumb,
|
||||
& div[class^=highlight] pre::-webkit-scrollbar-thumb,
|
||||
& pre.literal-block::-webkit-scrollbar-thumb {
|
||||
background-color: #99A0A5;
|
||||
border-radius: 8px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* copy code div */
|
||||
.highlight > .copyDiv {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: transform linear 250ms, width linear 250ms;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
padding: 5px 12px;
|
||||
justify-content: end;
|
||||
background-color: #393C3F;
|
||||
height: 32px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.copiedNotifier > span {
|
||||
font-size: 14px !important;
|
||||
color: #fff !important;
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
|
||||
& .kn {
|
||||
color: #ccffda;
|
||||
}
|
||||
|
||||
& .nn {
|
||||
color: #d0eefb;
|
||||
}
|
||||
|
||||
& .o {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
& .s2 {
|
||||
color: #dbe6f0;
|
||||
}
|
||||
|
||||
& .s1 {
|
||||
color: #dbe6f0;
|
||||
}
|
||||
|
||||
& .nb {
|
||||
color: #ccffda;
|
||||
}
|
||||
|
||||
& .c1 {
|
||||
color: #dcebef;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
& .nt {
|
||||
color: #8db1fe;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .k {
|
||||
color: #ccffda;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .se {
|
||||
color: #dbe6f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .nv {
|
||||
color: #eed7f4;
|
||||
}
|
||||
|
||||
& .gh {
|
||||
color: #ccccff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .gd {
|
||||
color: #ffcccc;
|
||||
}
|
||||
|
||||
& .gi {
|
||||
color: #ccffcc;
|
||||
}
|
||||
|
||||
& .gu {
|
||||
color: #ffc2ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .na {
|
||||
color: #81c0ff;
|
||||
}
|
||||
|
||||
& .s {
|
||||
color: #dbe6f0;
|
||||
}
|
||||
|
||||
& .ni {
|
||||
color: #f4d4cd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .cm {
|
||||
color: #d5e7ec;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
& .cp {
|
||||
color: #c2ffd3;
|
||||
}
|
||||
|
||||
& .mi {
|
||||
color: #cef3e0;
|
||||
}
|
||||
|
||||
& .nf {
|
||||
color: #c5d4fc;
|
||||
}
|
||||
|
||||
& .kc {
|
||||
color: #c2ffd3;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .ch {
|
||||
color: #d5e7ec;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
& .mf {
|
||||
color: #d6f5e6;
|
||||
}
|
||||
|
||||
& .go {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
& .m {
|
||||
color: #d6f5e6;
|
||||
}
|
||||
}
|
||||
|
||||
.rst-content blockquote {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.rst-content div:has(ul + blockquote) blockquote {
|
||||
margin: 15px 0 15px 24px
|
||||
}
|
||||
|
||||
@media screen and (max-width: 991px) {
|
||||
.rst-content .linenodiv pre,
|
||||
.rst-content div[class^=highlight] pre,
|
||||
.rst-content pre.literal-block {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.copyDiv > p {
|
||||
margin: 0 10px 0 0;
|
||||
color: #fff;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) {
|
||||
.rst-content .linenodiv pre,
|
||||
.rst-content div[class^=highlight] pre,
|
||||
.rst-content pre.literal-block {
|
||||
padding: 24px 36px 18px;
|
||||
}
|
||||
|
||||
.copyDiv > p {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
23
docs/_static/css/configuration/index.css
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#configuration-guide > div > ul > li {
|
||||
list-style: none !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#configuration-guide > div > ul > li::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
left: -15px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #000;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#configuration-guide .toctree-l1 > a {
|
||||
color: #FD8F01;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
722
docs/_static/css/custom.css
vendored
@ -1,193 +1,3 @@
|
||||
div.card-header {
|
||||
font-weight: bold;
|
||||
background: #fdab10;
|
||||
}
|
||||
|
||||
span.opcmd,
|
||||
span.cfgcmd {
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-size: 100% !important;
|
||||
max-width: 100%;
|
||||
color: #000;
|
||||
font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;
|
||||
}
|
||||
|
||||
span.cfgcmd:before {
|
||||
content: "#";
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
td a.cmdlink span.cfgcmd:before,
|
||||
td a.cmdlink span.opcmd:before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
td a.cmdlink,
|
||||
td a.cmdlink {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
tr td p {
|
||||
margin-bottom:0px
|
||||
}
|
||||
|
||||
span.opcmd:before {
|
||||
content: "$";
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.cfgcmd-heading {
|
||||
display: inline-block;
|
||||
margin: 6px 0;
|
||||
font-size: 90%;
|
||||
line-height: normal;
|
||||
background: #f0d481;
|
||||
color: #2980B9;
|
||||
border-top: solid 3px #6ab0de;
|
||||
border-top-width: 3px;
|
||||
border-top-style: solid;
|
||||
border-top-color: #FF9302;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.opcmd-heading {
|
||||
display: inline-block;
|
||||
margin: 6px 0;
|
||||
font-size: 90%;
|
||||
line-height: normal;
|
||||
background: #e7f2fa;
|
||||
color: #2980B9;
|
||||
border-top: solid 3px #6ab0de;
|
||||
border-top-width: 3px;
|
||||
border-top-style: solid;
|
||||
border-top-color: rgb(106, 176, 222);
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.opcmd-body,
|
||||
.cfgcmd-body {
|
||||
margin: 6px 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.cfgcmd-heading .cmdlink:after,
|
||||
.opcmd-heading .cmdlink:after{
|
||||
content: "";
|
||||
font-family: FontAwesome
|
||||
}
|
||||
|
||||
|
||||
.cfgcmd-heading:not(:hover) .cmdlink,
|
||||
.opcmd-heading:not(:hover) .cmdlink {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.defaultvalue{
|
||||
font-size: 90%;
|
||||
color: gray;
|
||||
margin-bottom: 5px;
|
||||
|
||||
}
|
||||
|
||||
a.cmdlink {
|
||||
font-size: 80%;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
a.cmdlink span{
|
||||
color: #2980B9;
|
||||
}
|
||||
|
||||
a.cmdlink span:hover{
|
||||
color: #3091d1;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
max-width : none;
|
||||
}
|
||||
|
||||
.wy-tray-container li.wy-tray-item-info {
|
||||
background : #409ad5;
|
||||
}
|
||||
|
||||
.wy-table-responsive {
|
||||
overflow : visible !important;
|
||||
}
|
||||
|
||||
.wy-table-responsive table td {
|
||||
white-space : normal !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical header,
|
||||
.wy-menu-vertical p.caption {
|
||||
color : #ffcc00 !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical li.current a {
|
||||
color : #040077 !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical li ul li a {
|
||||
color : #ffffff !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical a {
|
||||
color : #ffffff !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical a:active {
|
||||
background-color : #409ad5 !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search {
|
||||
background-color : #ffffff !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search img {
|
||||
background-color : #ffffff !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search > div.version {
|
||||
color : #000000 !important;
|
||||
}
|
||||
|
||||
.wy-side-nav-search>a,
|
||||
.wy-side-nav-search .wy-dropdown>a {
|
||||
color:#000000;
|
||||
font-size:100%;
|
||||
font-weight:bold;
|
||||
display:inline-block;
|
||||
padding:4px 6px;
|
||||
margin-bottom:.809em
|
||||
}
|
||||
|
||||
.wy-nav-top {
|
||||
background-color : #ffffff;
|
||||
}
|
||||
|
||||
.wy-nav-top img {
|
||||
background-color : #000000 !important;
|
||||
}
|
||||
|
||||
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td.coverage-ok,
|
||||
.rst-content table.docutils td.coverage-ok {
|
||||
color: green;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td.coverage-fail,
|
||||
.rst-content table.docutils td.coverage-fail {
|
||||
color: red;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
|
||||
p.devwarning {
|
||||
top: 10px;
|
||||
position: sticky;
|
||||
@ -197,19 +7,529 @@ p.devwarning {
|
||||
letter-spacing: 1px;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
background: #d40 repeating-linear-gradient( 135deg, transparent, transparent 56px, rgba(255, 255, 255, 0.2) 56px, rgba(255, 255, 255, 0.2) 112px );
|
||||
background-color: #fdab10;
|
||||
background: #d40
|
||||
repeating-linear-gradient(
|
||||
135deg,
|
||||
transparent,
|
||||
transparent 56px,
|
||||
rgba(255, 255, 255, 0.2) 56px,
|
||||
rgba(255, 255, 255, 0.2) 112px
|
||||
);
|
||||
background-color: #fdab10;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.wy-nav-top{
|
||||
background-color: #fdab10;
|
||||
}
|
||||
/* main page */
|
||||
.wy-body-for-nav {
|
||||
background: #fff;
|
||||
overflow-y: hidden
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
p.devwarning {
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
.wy-grid-for-nav {
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
padding-top: 80px;
|
||||
display: flex;
|
||||
|
||||
&:has(nav.wy-nav-side.shift) {
|
||||
background: #E7E7E7;
|
||||
}
|
||||
|
||||
&:not(:has(nav.shift)) > section > div.overlay {
|
||||
background-color: transparent
|
||||
}
|
||||
|
||||
&:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li a::before,
|
||||
&:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li a::after,
|
||||
&:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li::before,
|
||||
&:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li::after {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap {
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
max-width: 100%;
|
||||
background-color: transparent;
|
||||
|
||||
&.overlay > div > div[role=navigation] .wy-breadcrumbs > li a::before,
|
||||
&.overlay > div > div[role=navigation] .wy-breadcrumbs > li a::after,
|
||||
&.overlay > div > div[role=navigation] .wy-breadcrumbs > li::before,
|
||||
&.overlay > div > div[role=navigation] .wy-breadcrumbs > li::after,
|
||||
&.overlay > div > div.document div.sd-card,
|
||||
&.overlay > div > div.document div.sd-card-title {
|
||||
background-color: #E7E7E7;
|
||||
}
|
||||
|
||||
&.overlay > div.rst-content > footer > .rst-footer-buttons > a {
|
||||
background-color: #E7E7E7 !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* main-page content */
|
||||
#vyos-user-guide {
|
||||
& .sd-container-fluid {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
& .sd-container-fluid > .docutils > .sd-col {
|
||||
max-width: 387px;
|
||||
box-shadow: none;
|
||||
flex: none;
|
||||
width: 100% !important;
|
||||
padding: 0 !important;
|
||||
margin-top: 0 !important;
|
||||
|
||||
& .sd-card-body .sd-card-text {
|
||||
min-height: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
& > div.sd-container-fluid {
|
||||
margin-top: 30px;
|
||||
|
||||
& > div.docutils {
|
||||
margin: 0;
|
||||
display: grid;
|
||||
}
|
||||
}
|
||||
|
||||
& > .pb-4 {
|
||||
padding-bottom: 1.4rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
div.sd-card-title {
|
||||
font-weight: bold;
|
||||
background: #fff;
|
||||
border: none;
|
||||
font-family: 'Archivo', sans-serif;
|
||||
}
|
||||
|
||||
.sd-card {
|
||||
background: #fff;
|
||||
border: none;
|
||||
border-bottom: 1px solid #ffae12;
|
||||
border-radius: 0;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.sd-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sd-card-title,
|
||||
.sd-card-text {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.internal > .std-ref,
|
||||
.line > .external {
|
||||
color: #fd8f01;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
img {
|
||||
height: auto !important;
|
||||
border: 1px solid #C4C9CC;
|
||||
margin-bottom: 20px !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.5px;
|
||||
color: #636a6d;
|
||||
|
||||
& > a {
|
||||
color: #fd8f01;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
& > hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& p {
|
||||
margin-top: 105px;
|
||||
text-align: center;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.5px;
|
||||
color: #636a6d;
|
||||
|
||||
&:has(a) > a,
|
||||
&:has(a) > a:visited {
|
||||
color: #636a6d;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.rst-versions {
|
||||
position: static;
|
||||
background: transparent;
|
||||
width: 262px;
|
||||
display: block;
|
||||
|
||||
&.shift-up {
|
||||
background: #525659;
|
||||
z-index: 100;
|
||||
position: absolute;
|
||||
left: 19px;
|
||||
bottom: 30px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& .rst-current-version {
|
||||
background-color: #525659;
|
||||
color: #01D38E;
|
||||
border-radius: 6px;
|
||||
width: 264px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
& .rst-current-version span.fa-book {
|
||||
color: #fff !important;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
}
|
||||
|
||||
.rst-other-versions {
|
||||
& dt {
|
||||
color: #808080;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
& small {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
color: #fff;
|
||||
|
||||
& a {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
letter-spacing: -0.5px;
|
||||
color: #fd8f01;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
div#rtd-sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wy-nav-content-opened-sidebar {
|
||||
padding: 25px 0 27px 40px;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap-opened-sidebar {
|
||||
max-width: calc(100% - 294px);
|
||||
margin-left: 294px;
|
||||
}
|
||||
|
||||
.wy-nav-content-closed-sidebar {
|
||||
padding: 26px 0 !important;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap-closed-sidebar {
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-padding-top: 90px !important;
|
||||
}
|
||||
|
||||
.overlayDiv {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 111;
|
||||
background-color: #121010;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.iframe-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background-color: #f0f0f0;
|
||||
z-index: 201;
|
||||
overflow: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media screen and (min-width: 320px) and (max-width: 575px) {
|
||||
#vyos-user-guide .container > .row {
|
||||
grid-gap: 0px 15px
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
.wy-nav-content-wrap,
|
||||
.wy-nav-content-wrap.shift {
|
||||
max-width: 100%;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap.shift {
|
||||
padding: 70px 15px 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.wy-nav-side {
|
||||
display: none;
|
||||
min-height: unset;
|
||||
}
|
||||
|
||||
.wy-nav-side.shift {
|
||||
display: inherit;
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
#vyos-user-guide .container > .docutils > .p-2 {
|
||||
max-width: 100%;
|
||||
&:nth-child(2n) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
& .card-body .card-text {
|
||||
min-height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap-opened-sidebar {
|
||||
max-width: 100%;
|
||||
margin-left: unset;
|
||||
}
|
||||
|
||||
dl.footnote > dt {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.wy-grid-for-nav {
|
||||
padding: 80px 20px 0;
|
||||
max-width: 738px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 575px) and (max-width: 768px) {
|
||||
.wy-nav-content-wrap,
|
||||
.wy-nav-content-wrap.shift {
|
||||
max-width: 100%;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap.shift {
|
||||
padding: 70px 15px 0;
|
||||
overflow: auto;
|
||||
width: calc(100% - 294px);
|
||||
|
||||
}
|
||||
|
||||
.wy-nav-side {
|
||||
display: none;
|
||||
min-height: unset;
|
||||
}
|
||||
|
||||
.wy-nav-side.shift {
|
||||
display: inherit;
|
||||
width: 294px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 575px) {
|
||||
#vyos-user-guide div.sd-container-fluid > div.docutils {
|
||||
grid-gap: 30px;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.wy-nav-content-wrap,
|
||||
.wy-nav-content-wrap.shift {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wy-nav-top {
|
||||
background-color: #fdab10;
|
||||
}
|
||||
|
||||
p.devwarning {
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
|
||||
#vyos-user-guide .container {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap .wy-nav-content {
|
||||
padding: 0 0 26px 0;
|
||||
}
|
||||
|
||||
.wy-grid-for-nav {
|
||||
padding: 80px 15px 0;
|
||||
max-width: 738px;
|
||||
}
|
||||
|
||||
.rst-content > div > hr {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.wy-nav-content-wrap {
|
||||
width: calc(100% - 292px);
|
||||
}
|
||||
|
||||
.rst-content > div > hr {
|
||||
margin: 16px 0 26px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) and (max-width: 991px) {
|
||||
.wy-nav-content {
|
||||
padding: 25px 0 27px 40px;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap {
|
||||
max-width: calc(100% - 294px);
|
||||
}
|
||||
|
||||
.wy-grid-for-nav {
|
||||
max-width: 738px;
|
||||
padding: 70px 15px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) and (max-width: 1266px) {
|
||||
.wy-nav-content {
|
||||
padding: 25px 0 27px 40px;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap {
|
||||
max-width: calc(100% - 294px);
|
||||
}
|
||||
|
||||
.wy-grid-for-nav {
|
||||
max-width: calc(100% - 130px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1266px) {
|
||||
.wy-nav-content {
|
||||
padding: 25px 0 27px 40px;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap {
|
||||
max-width: calc(100% - 294px);
|
||||
}
|
||||
|
||||
.wy-grid-for-nav {
|
||||
max-width: 1140px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.wy-nav-content {
|
||||
padding: 25px 0 27px 40px;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap {
|
||||
max-width: calc(100% - 294px);
|
||||
}
|
||||
|
||||
.wy-grid-for-nav {
|
||||
max-width: 1340px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 500px) {
|
||||
.rst-versions {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.closeButtonDivLine {
|
||||
bottom: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 501px) and (max-height: 1000px) {
|
||||
.rst-versions {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.closeButtonDivLine {
|
||||
bottom: 55px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 1001px) and (max-height: 1300px) {
|
||||
.rst-versions {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.closeButtonDivLine {
|
||||
bottom: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 1301px) and (max-height: 1600px) {
|
||||
.rst-versions {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.closeButtonDivLine {
|
||||
bottom: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 1601px) {
|
||||
.rst-versions {
|
||||
margin-top: 35px;
|
||||
}
|
||||
|
||||
.closeButtonDivLine {
|
||||
bottom: 85px;
|
||||
}
|
||||
}
|
||||
134
docs/_static/css/headers.css
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
font-family: 'Archivo', sans-serif !important;
|
||||
font-weight: 700 !important;
|
||||
letter-spacing: -0.02em !important;
|
||||
display: flex;
|
||||
color: #121010;
|
||||
margin-bottom: 15px !important;
|
||||
}
|
||||
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
margin-top: 15px !important;
|
||||
}
|
||||
|
||||
h1:has(a) > a,
|
||||
h2:has(a) > a,
|
||||
h3:has(a) > a,
|
||||
h4:has(a) > a,
|
||||
h5:has(a) > a {
|
||||
display: flex !important;
|
||||
position: relative;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
h1 {
|
||||
font-size: 28px !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
h1 {
|
||||
font-size: 48px !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 34px !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 991px) {
|
||||
h1 {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
opacity: 1 !important;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
h1:has(a):hover > a::after,
|
||||
h2:has(a):hover > a::after,
|
||||
h3:has(a):hover > a::after,
|
||||
h4:has(a):hover > a::after,
|
||||
h5:has(a):hover > a::after {
|
||||
content: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
h1:has(a) > a::before,
|
||||
h2:has(a) > a::before,
|
||||
h3:has(a) > a::before,
|
||||
h4:has(a) > a::before,
|
||||
h5:has(a) > a::before {
|
||||
content: url('../images/cmnd-link-icon.svg');
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
z-index: 2;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) {
|
||||
h1:has(a):hover > a::after,
|
||||
h2:has(a):hover > a::after,
|
||||
h3:has(a):hover > a::after,
|
||||
h4:has(a):hover > a::after,
|
||||
h5:has(a):hover > a::after {
|
||||
content: url('../images/cmnd-link-icon.svg');
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
z-index: 2;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
123
docs/_static/css/hints.css
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
div {
|
||||
&.note,
|
||||
&.hint,
|
||||
&.warning,
|
||||
&.error,
|
||||
&.seealso,
|
||||
&.tip {
|
||||
border-radius: 8px;
|
||||
|
||||
& > .admonition-title {
|
||||
padding: 5px 8px;
|
||||
border-radius: 6px;
|
||||
font-family: 'Archivo', sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
letter-spacing: -0.02em !important;
|
||||
font-weight: 600 !important;
|
||||
margin: -12px -16px 12px;
|
||||
}
|
||||
|
||||
& > .admonition-title::before {
|
||||
content: url('../images/note-icon.svg');
|
||||
}
|
||||
|
||||
& > .highlight-none {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
& > p:nth-child(1n+2) {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
color: #525659;
|
||||
font-weight: 400;
|
||||
margin: 10px 0 0 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.note,
|
||||
&.seealso {
|
||||
background-color: #F5FCFF !important;
|
||||
}
|
||||
|
||||
&.note:has(a.reference),
|
||||
&.hint:has(a.reference),
|
||||
&.warning:has(a.reference),
|
||||
&.error:has(a.reference),
|
||||
&.seealso:has(a.reference),
|
||||
&.tip:has(a.reference) {
|
||||
& a.reference,
|
||||
& a.reference span {
|
||||
color: #508EEB !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.note,
|
||||
&.seealso {
|
||||
& > .admonition-title {
|
||||
background-color: #CCEFFB !important;
|
||||
color: #356E81 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.hint,
|
||||
&.tip {
|
||||
background-color: #F7FDFB !important;
|
||||
|
||||
& > .admonition-title {
|
||||
background-color: #C6F0E3 !important;
|
||||
color: #3F6461 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.warning,
|
||||
&.error {
|
||||
background-color: #FDF7F7 !important;
|
||||
|
||||
& > .admonition-title {
|
||||
background-color: #F0C6C6 !important;
|
||||
color: #8E2F2F !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#running-on-bare-metal div.note > p:nth-child(2) {
|
||||
padding: 8px 12px 0 12px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
div.note,
|
||||
div.hint,
|
||||
div.warning,
|
||||
div.error,
|
||||
div.seealso,
|
||||
div.tip {
|
||||
padding: 24px 32px !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 576px) and (max-width: 991px) {
|
||||
div.note,
|
||||
div.hint,
|
||||
div.warning,
|
||||
div.error,
|
||||
div.seealso,
|
||||
div.tip {
|
||||
padding: 24px 32px !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) {
|
||||
div.note,
|
||||
div.hint,
|
||||
div.warning,
|
||||
div.error,
|
||||
div.seealso,
|
||||
div.tip {
|
||||
padding: 24px 32px !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
11
docs/_static/css/installation/running-on-bare-metal.css
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
.toctree-l1 {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.current > .current > .internal {
|
||||
background-color: #fff;
|
||||
color: #FD8F01;
|
||||
border: transparent;
|
||||
padding: 11px 12px 11px 28px;
|
||||
border: none !important;
|
||||
}
|
||||
371
docs/_static/css/leftSidebar.css
vendored
Normal file
@ -0,0 +1,371 @@
|
||||
nav.wy-nav-side {
|
||||
padding-bottom: 1em !important;
|
||||
}
|
||||
|
||||
.wy-nav-side {
|
||||
padding: 20px 19px;
|
||||
width: 294px;
|
||||
height: calc(100vh - 50px);
|
||||
}
|
||||
|
||||
.wy-form input {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.wy-form input::placeholder {
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.wy-side-nav-search {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
& > .icon-home,
|
||||
& > .version {
|
||||
display: none
|
||||
}
|
||||
|
||||
& input {
|
||||
border-color: #C4C9CC;
|
||||
|
||||
&::placeholder {
|
||||
color: #8D9499;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wy-nav-side,
|
||||
.wy-nav-side .wy-side-nav-search {
|
||||
background-color: #F6F7F7
|
||||
}
|
||||
|
||||
ul.current > li.toctree-l1[aria-expanded=false] > a.current {
|
||||
padding-left: 25px;
|
||||
color: #FD8F01;
|
||||
|
||||
& button.toctree-expand::before {
|
||||
content: '+';
|
||||
color: #FD8F01;
|
||||
}
|
||||
}
|
||||
|
||||
ul.current > li.toctree-l1[aria-expanded=false] > a.internal:has( + ul[aria-expanded=false]) {
|
||||
padding-left: 25px;
|
||||
color: #FD8F01;
|
||||
|
||||
& button.toctree-expand::before {
|
||||
content: '+';
|
||||
color: #FD8F01;
|
||||
}
|
||||
}
|
||||
|
||||
ul.current > li.toctree-l1.current > ul > li.toctree-l2[aria-expanded=false]:has(ul > li > a.current) > a.internal {
|
||||
color: #FD8F01;
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
ul.current > li.toctree-l1.current >
|
||||
ul > li.toctree-l2.current > ul > li.toctree-l3[aria-expanded=false]
|
||||
> a.current {
|
||||
color: #FD8F01;
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
ul.current > li.toctree-l1.current >
|
||||
ul > li.toctree-l2.current > ul > li.toctree-l3[aria-expanded=false]:has(ul > li.toctree-l4 > a.current)
|
||||
> a.internal {
|
||||
color: #FD8F01;
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.toctree-l2 > ul > li.toctree-l3.current {
|
||||
padding-left: 0 !important;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.wy-menu-vertical {
|
||||
width: 100%;
|
||||
max-width: 292px;
|
||||
|
||||
& a {
|
||||
color: #121010;
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.02em;
|
||||
padding: 11px 12px;
|
||||
}
|
||||
|
||||
& p.caption {
|
||||
color: #8D9499;
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.02em;
|
||||
padding: 5px 12px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 4px;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current > a {
|
||||
background-color: #fff;
|
||||
color: #FD8F01;
|
||||
border: transparent;
|
||||
padding: 11px 12px;
|
||||
}
|
||||
|
||||
& > ul.current > li.toctree-l1.current > a.internal:has(+ ul) {
|
||||
padding-left: 25px !important;
|
||||
}
|
||||
|
||||
& > ul.current > li.toctree-l1.current > a.current {
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current .toctree-l2 > a {
|
||||
background-color: #fff;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current .toctree-l2 > a.internal {
|
||||
padding-left: 35px !important;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current .toctree-l2.current > a.internal:first-of-type {
|
||||
color: #fdab10;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current .toctree-l2 > a:hover {
|
||||
background-color: #E1E4E5;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current .toctree-l2 > a.current {
|
||||
color: #fdab10;
|
||||
padding: 11px 12px 11px 35px;
|
||||
}
|
||||
|
||||
& li.toctree-l1.current .toctree-l2 > a:hover {
|
||||
background-color: #E1E4E5;
|
||||
}
|
||||
|
||||
& li.toctree-l2.current > a,
|
||||
& li.toctree-l2.current li.toctree-l3 > a {
|
||||
background: #fff;
|
||||
border: none;
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
& li.toctree-l2.current li.toctree-l3 > a.current,
|
||||
& li.toctree-l2.current li.toctree-l3.current > a.internal {
|
||||
padding-left: 50px !important;
|
||||
color: #fdab10;
|
||||
}
|
||||
|
||||
& li.toctree-l3.current li.toctree-l4 > a {
|
||||
background: #fff;
|
||||
padding-left: 65px !important;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
& li.toctree-l3.current li.toctree-l4 > a.current {
|
||||
color: #fdab10;
|
||||
}
|
||||
}
|
||||
|
||||
.wy-menu-vertical a:hover,
|
||||
.wy-menu-vertical > ul.current > li.toctree-l1.current > a:hover,
|
||||
.wy-menu-vertical li.toctree-l1.current .toctree-l2 > a:hover,
|
||||
.wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a:hover,
|
||||
.wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a:hover {
|
||||
background-color: #E1E4E5;
|
||||
}
|
||||
|
||||
.wy-menu-vertical ul li .current > a {
|
||||
padding: 11px 12px !important;
|
||||
}
|
||||
|
||||
.wy-menu-vertical > ul.current[aria-expanded=true] > li.toctree-l1:has(a[aria-expanded=false]) > a {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.wy-menu-vertical > ul.current[aria-expanded=true] > li.toctree-l1:not(:has( ~ li:only-child a)) > a:has(.toctree-expand) {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.wy-side-scroll {
|
||||
/* that makes scroll possible to the end of div */
|
||||
height: 94%;
|
||||
}
|
||||
|
||||
.wy-nav-top {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.openLeftSidebarMenuButton {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
transition: transform 250ms linear;
|
||||
}
|
||||
|
||||
.openLeftSidebarMenuButton:hover,
|
||||
.closeLeftSidebarMenuButton:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
div.wy-nav-content > div.rst-content > div:has(div.openLeftSidebarMenuButton) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div.wy-nav-content
|
||||
> div.rst-content
|
||||
> div:has(div.openLeftSidebarMenuButton)
|
||||
> .wy-breadcrumbs {
|
||||
margin-left: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.closeButtonDivLine {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
position: sticky;
|
||||
height: 30px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.closeLeftSidebarMenuButton {
|
||||
width: 83px;
|
||||
height: 32px;
|
||||
margin-right: -6px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #FFBF12;
|
||||
border-radius: 4px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
font-weight: 400;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
align-self: flex-end;
|
||||
transition: transform 250ms linear;
|
||||
|
||||
&::before {
|
||||
content: url('../images/close-sidebar-icon.svg');
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 14px;
|
||||
margin-right: 10px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.additionalStylesForShift {
|
||||
display: block !important;
|
||||
padding-bottom: 10px !important;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
background-color: #E7E7E7;
|
||||
}
|
||||
|
||||
.wy-body-for-nav:has(.overlay) {
|
||||
background-color: rgb(209,209,209);
|
||||
}
|
||||
|
||||
.display_none {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
.wy-menu-vertical {
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 576px) {
|
||||
.wy-side-nav-search {
|
||||
max-width: 256px;
|
||||
}
|
||||
|
||||
.wy-menu-vertical {
|
||||
padding: 10px 35px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.wy-nav-side {
|
||||
border-radius: 0;
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.wy-side-scroll::-webkit-scrollbar {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.wy-nav-side {
|
||||
border-radius: 16px;
|
||||
position: fixed;
|
||||
left: unset;
|
||||
top: 70px;
|
||||
min-height: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.wy-nav-side {
|
||||
height: calc(100vh - 60px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1200px) {
|
||||
.wy-nav-side {
|
||||
height: calc(100vh - 73px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 300px) {
|
||||
.wy-side-scroll {
|
||||
height: 78%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 301px) and (max-height: 400px) {
|
||||
.wy-side-scroll {
|
||||
height: 82%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 401px) and (max-height: 500px) {
|
||||
.wy-side-scroll {
|
||||
height: 88%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 501px) and (max-height: 700px) {
|
||||
.wy-side-scroll {
|
||||
height: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 701px) {
|
||||
.wy-side-scroll {
|
||||
height: 94%;
|
||||
}
|
||||
}
|
||||
57
docs/_static/css/linkButtons.css
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
.rst-footer-buttons {
|
||||
.fa-arrow-circle-left {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.fa-arrow-circle-left::before {
|
||||
content: url('../images/arrow-left.svg');
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
& > .btn-neutral {
|
||||
background: #fff !important;
|
||||
min-width: 90px;
|
||||
height: 40px;
|
||||
border: 2px solid #FD8F01;
|
||||
color: #121010 !important;
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
box-shadow: none;
|
||||
transition: transform 250ms linear;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
transform: scale(1.05);
|
||||
/* padding-left: 16px; */
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.fa-arrow-circle-right::before {
|
||||
content: url('../images/arrow-right.svg');
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p > a.reference.external,
|
||||
p > a,
|
||||
#partaker-i5 > p > a.external {
|
||||
color: #FD8F01;
|
||||
word-break: break-word;
|
||||
}
|
||||
56
docs/_static/css/lists.css
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
.simple > li,
|
||||
.compound > ul > li,
|
||||
.simple > li > ul > li,
|
||||
#installation-and-image-management > div > ul > li.toctree-l1 > ul > li.toctree-l2,
|
||||
#running-vyos-in-virtual-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2,
|
||||
#running-vyos-in-virtual-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3,
|
||||
#running-vyos-in-cloud-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2,
|
||||
#running-vyos-in-cloud-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3,
|
||||
#configuration-blueprints > div > ul > li.toctree-l1 > ul > li.toctree-l2,
|
||||
#configuration-blueprints > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3,
|
||||
#contributing > div > ul > li.toctree-l1 > ul > li.toctree-l2,
|
||||
#contributing > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3 {
|
||||
list-style: none !important;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: -15px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #000;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.simple > li a,
|
||||
.compound > ul > li a,
|
||||
.simple > li > ul > li a {
|
||||
color: #FD8F01;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.5px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.simple > li > ul > li p {
|
||||
color: #525659;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.5px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
#site-to-site ul,
|
||||
#troubleshooting ol,
|
||||
#troubleshooting ul {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.rst-content:has(#troubleshooting) .rst-footer-buttons {
|
||||
margin-top: 20px !important;
|
||||
}
|
||||
20
docs/_static/css/scrolls.css
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
.wy-table-responsive {
|
||||
scrollbar-color: #99A0A5 transparent;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
border-radius: 8px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: #99A0A5;
|
||||
border-radius: 8px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
116
docs/_static/css/separate-commands.css
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
.rst-content code.literal {
|
||||
border: unset;
|
||||
background-color: unset;
|
||||
border: 1px solid rgba(253, 143, 1, 0.2);
|
||||
background-color: #FFF4E6;
|
||||
font-family: 'Archivo', sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 500 !important;
|
||||
color: #121010 !important;
|
||||
border-radius: 4px;
|
||||
padding: 3px 6px;
|
||||
word-break: break-all;
|
||||
|
||||
& > span.pre:nth-child(n+ 2) {
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
div.opcmd-heading,
|
||||
div.cfgcmd-heading,
|
||||
table .opcmd,
|
||||
table .cfgcmd {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
background-color: unset;
|
||||
border: none;
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
div.opcmd-heading,
|
||||
div.cfgcmd-heading {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
div.opcmd-heading,
|
||||
table .opcmd {
|
||||
border-left: 5px solid #B8E9F9;
|
||||
}
|
||||
|
||||
div.cfgcmd-heading,
|
||||
table .cfgcmd {
|
||||
border-left: 5px solid #FD8F01;
|
||||
}
|
||||
|
||||
span {
|
||||
&.opcmd,
|
||||
&.cfgcmd {
|
||||
display: flex;
|
||||
padding: 4px 8px 8px 30px;
|
||||
align-items: center;
|
||||
color: #121010 !important;
|
||||
font-family: 'Roboto Mono', monospace !important;
|
||||
letter-spacing: -0.04em !important;
|
||||
font-weight: 500 !important;
|
||||
position: relative;
|
||||
word-break: break-all;
|
||||
|
||||
&::before {
|
||||
content: url('../images/cmnd-link-dollar-icon.svg');
|
||||
display: flex;
|
||||
padding-right: 8px;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.opcmd {
|
||||
background-color: #EBF9FF;
|
||||
}
|
||||
|
||||
&.cfgcmd {
|
||||
background-color: #FFF4E6;
|
||||
}
|
||||
}
|
||||
|
||||
span.opcmd,
|
||||
span.cfgcmd {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
table span.opcmd,
|
||||
table span.cfgcmd {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.opcmd-heading > a.cmdlink,
|
||||
.cfgcmd-heading > a.cmdlink {
|
||||
display: flex;
|
||||
|
||||
&::after {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
content: '';
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
padding-right: 12px;
|
||||
padding-top: 3px;
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.opcmd-heading:hover a.cmdlink:after,
|
||||
.cfgcmd-heading:hover a.cmdlink:after {
|
||||
content: url('../images/cmnd-link-icon.svg');
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.opcmd-heading a.cmdlink:after {
|
||||
background-color: #EBF9FF;
|
||||
}
|
||||
|
||||
.cfgcmd-heading a.cmdlink:after {
|
||||
background-color: #FFF4E6;
|
||||
}
|
||||
231
docs/_static/css/tables.css
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
.wy-table-responsive {
|
||||
overflow : auto !important ;
|
||||
width: 100%;
|
||||
|
||||
& table {
|
||||
border: none !important;
|
||||
|
||||
|
||||
& td {
|
||||
white-space : normal !important;
|
||||
}
|
||||
|
||||
& > caption:hover a {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: url('../images/cmnd-link-icon.svg');
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -3px;
|
||||
z-index: 2;
|
||||
background-color: #fff;
|
||||
width: 20px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#coverage table.docutils td.coverage-ok p {
|
||||
color: green;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#coverage table.docutils:not(.field-list) tr:nth-child(2n-1) td.coverage-fail p,
|
||||
#coverage table.docutils td.coverage-fail p {
|
||||
color: red;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#coverage a.paginate_button.current,
|
||||
#coverage a.paginate_button.next,
|
||||
#coverage a.paginate_button.previous {
|
||||
color: #FD8F01 !important;
|
||||
background-color: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#coverage a.paginate_button {
|
||||
margin-left: 0;
|
||||
border: unset;
|
||||
border-radius: 8px;
|
||||
transition: background-color 250ms linear, color 250ms linear;
|
||||
}
|
||||
|
||||
#coverage a.paginate_button:hover,
|
||||
#coverage a.paginate_button.current:hover,
|
||||
#coverage a.paginate_button.next:hover,
|
||||
#coverage a.paginate_button.previous:hover {
|
||||
background-color: #E1E4E5 !important;
|
||||
background: none;
|
||||
border: unset;
|
||||
color: #121010 !important;
|
||||
}
|
||||
|
||||
.selectDiv {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 11111;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
#table-cfgcmd_wrapper,
|
||||
#table-opcmd_wrapper {
|
||||
& label {
|
||||
color: #121010 !important;
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
& option {
|
||||
color: #8D9499 !important;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
& select {
|
||||
height: 40px;
|
||||
width: 80px;
|
||||
padding: 10px 14px;
|
||||
margin: 0 10px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #C6C9CC !important;
|
||||
color: #8D9499;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background-image: url("../images/select-arrow.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 18px top 50%;
|
||||
}
|
||||
|
||||
& input {
|
||||
margin-left: 16px;
|
||||
height: 40px;
|
||||
padding: 10px 14px;
|
||||
width: 245px;
|
||||
border: 1px solid #C6C9CC !important;
|
||||
color: #8D9499;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
& .wy-table-responsive {
|
||||
padding-top: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
#table-cfgcmd_wrapper,
|
||||
#table-opcmd_wrapper {
|
||||
& label {
|
||||
& input {
|
||||
margin-top: 10px
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thead tr th {
|
||||
padding: 10px 16px !important;
|
||||
border-top: none !important;
|
||||
border-left: none !important;
|
||||
border-right: none !important;
|
||||
max-height: 40px;
|
||||
|
||||
& p {
|
||||
color: #121010 !important;
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.rst-content table.docutils td,
|
||||
.wy-table-bordered-all td {
|
||||
border-left: none !important;
|
||||
}
|
||||
|
||||
.rst-content table.docutils th:nth-child(2n),
|
||||
.rst-content table.field-list th:nth-child(2n),
|
||||
.wy-table td, .wy-table th:nth-child(2n) {
|
||||
border-radius: 8px 8px 0 0 ;
|
||||
}
|
||||
|
||||
.wy-grid-for-nav:has(nav.display_none) .rst-content table.docutils td:nth-child(2n),
|
||||
.wy-grid-for-nav:has(nav.display_none) .rst-content table.docutils th:nth-child(2n),
|
||||
.wy-grid-for-nav:has(nav.display_none) .rst-content table.field-list td:nth-child(2n),
|
||||
.wy-grid-for-nav:has(nav.display_none) .rst-content table.field-list th:nth-child(2n),
|
||||
.wy-grid-for-nav:has(nav.display_none) .wy-table td,
|
||||
.wy-grid-for-nav:has(nav.display_none) .wy-table th:nth-child(2n) {
|
||||
background-color: #FAFAFA !important;
|
||||
}
|
||||
|
||||
.wy-grid-for-nav:has(nav.shift) .wy-nav-content-wrap-closed-sidebar .rst-content table th,
|
||||
.wy-grid-for-nav:has(nav.shift) .wy-nav-content-wrap-closed-sidebar .rst-content table td {
|
||||
background-color: #E7E7E7 !important;
|
||||
}
|
||||
|
||||
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,
|
||||
.wy-table-backed,
|
||||
.wy-table-odd td,
|
||||
.wy-table-striped tr:nth-child(2n-1) td {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
tbody tr td {
|
||||
& p {
|
||||
color: #525659 !important;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px !important;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
&.coverage-ok {
|
||||
& p {
|
||||
color: transparent !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: url('../images/check.svg');
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dataTables_info {
|
||||
color: #121010 !important;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px !important;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.paginate_button {
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
120
docs/_static/css/text.css
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
.docutils .card-header p {
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.05em;
|
||||
padding-bottom: 18px;
|
||||
color: #121010;
|
||||
}
|
||||
|
||||
p,
|
||||
blockquote > div > dl,
|
||||
blockquote > div > dd,
|
||||
#container dl,
|
||||
#firewall dl,
|
||||
#high-availability dl,
|
||||
#development td,
|
||||
#development th,
|
||||
caption.caption-text,
|
||||
.simple > dt,
|
||||
div.line-block,
|
||||
.paginate_button,
|
||||
.dataTables_info,
|
||||
#operational-commands label,
|
||||
.card-body .card-text,
|
||||
#search-results a {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
font-weight: 400;
|
||||
color: #525659;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
p > strong {
|
||||
color: #121010;
|
||||
}
|
||||
|
||||
.card-body .card-text {
|
||||
padding-bottom: 22px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.simple > dt {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#dual-hub-dmvpn-with-vyos td > p,
|
||||
#route-based-redundant-site-to-site-vpn-to-azure-bgp-over-ikev2-ipsec td > p,
|
||||
#route-based-site-to-site-vpn-to-azure-bgp-over-ikev2-ipsec td > p,
|
||||
#development td p,
|
||||
#development th p {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
#development #writing-good-commit-messages > ul.simple > li > ul {
|
||||
|
||||
& > li:nth-child(2) {
|
||||
padding-bottom: 23px;
|
||||
}
|
||||
|
||||
& > li:nth-child(2) {
|
||||
padding-bottom: 53px;
|
||||
}
|
||||
}
|
||||
|
||||
#installation-and-image-management > div > p > span {
|
||||
font-family: 'Archivo', sans-serif;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
font-size: 24px;
|
||||
color: #121010;
|
||||
}
|
||||
|
||||
.caption-text {
|
||||
text-align: left;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
p .caption-text {
|
||||
color: #8D9499;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
aside.footnote .label {
|
||||
& > a[role=doc-backlink] {
|
||||
color: #fd8f01;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
aside.footnote > p {
|
||||
padding-bottom: 15px !important;
|
||||
}
|
||||
|
||||
#about a .external,
|
||||
#a-note-on-copyright > dl.brackets > dt,
|
||||
#a-note-on-copyright > dl.brackets > dt > .brackets > a,
|
||||
a.footnote-reference.brackets,
|
||||
#search-results a {
|
||||
color: #FD8F01;
|
||||
}
|
||||
|
||||
#history p {
|
||||
padding-bottom: 22px;
|
||||
margin-bottom: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#a-note-on-copyright > dl p {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
#search-results a {
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
#specify-custom-config-file {
|
||||
padding-top: 15px;
|
||||
}
|
||||
BIN
docs/_static/images/IPSec_close_action_settings.jpg
vendored
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 69 KiB |
3
docs/_static/images/arrow-left.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="15" height="16" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 10.5L5.32396 10.5L10.1836 16.0076L7.93407 17.9924L-0.000432575 9L7.93406 0.0075688L10.1836 1.99243L5.32396 7.5L18 7.5L18 10.5Z" fill="#FFAE12"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 301 B |
3
docs/_static/images/arrow-right.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="15" height="16" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M-4.58639e-07 10.5L12.676 10.5L7.81642 16.0076L10.0659 17.9924L18.0004 9L10.0659 0.0075688L7.81642 1.99243L12.676 7.5L-3.27505e-07 7.5L-4.58639e-07 10.5Z" fill="#FFAE12"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
BIN
docs/_static/images/aws.png
vendored
Normal file
|
After Width: | Height: | Size: 147 KiB |
3
docs/_static/images/breadcrumbs-icon.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="7" height="10" viewBox="0 0 7 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 1L5 5L1 9" stroke="#8D9499" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 160 B |
3
docs/_static/images/check.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="15" viewBox="0 0 20 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 6L8 12L18 2" stroke="#FFAE12" stroke-width="3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 164 B |
3
docs/_static/images/close-sidebar-icon.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="15" height="16" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 10.5L5.32396 10.5L10.1836 16.0076L7.93407 17.9924L-0.000432575 9L7.93406 0.0075688L10.1836 1.99243L5.32396 7.5L18 7.5L18 10.5Z" fill="#FFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 297 B |
3
docs/_static/images/cmnd-link-dollar-icon.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="14" height="14" viewBox="0 0 7 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.36 2.992V0.877999H4.06V2.992H3.36ZM3.36 11.686V9.46H4.06V11.686H3.36ZM3.654 10.048C3.14067 10.048 2.688 9.99667 2.296 9.894C1.904 9.782 1.57733 9.628 1.316 9.432C1.05467 9.22667 0.854 8.98867 0.714 8.718C0.583333 8.438 0.518 8.13 0.518 7.794C0.518 7.74733 0.518 7.70533 0.518 7.668C0.527333 7.63067 0.532 7.598 0.532 7.57H1.974C1.974 7.598 1.974 7.626 1.974 7.654C1.974 7.67267 1.974 7.696 1.974 7.724C1.974 8.01333 2.05333 8.24667 2.212 8.424C2.37067 8.592 2.58067 8.71333 2.842 8.788C3.11267 8.85333 3.40667 8.886 3.724 8.886C4.004 8.886 4.26067 8.85333 4.494 8.788C4.73667 8.72267 4.93267 8.62 5.082 8.48C5.24067 8.33067 5.32 8.14867 5.32 7.934C5.32 7.654 5.222 7.43933 5.026 7.29C4.83 7.14067 4.57333 7.024 4.256 6.94C3.93867 6.84667 3.60733 6.75333 3.262 6.66C2.954 6.576 2.646 6.48267 2.338 6.38C2.03933 6.27733 1.76867 6.15133 1.526 6.002C1.28333 5.84333 1.08733 5.64267 0.938 5.4C0.788667 5.148 0.714 4.84 0.714 4.476C0.714 4.13067 0.788667 3.82733 0.938 3.566C1.08733 3.30467 1.29267 3.08533 1.554 2.908C1.82467 2.73067 2.142 2.59533 2.506 2.502C2.87933 2.40867 3.28533 2.362 3.724 2.362C4.18133 2.362 4.58733 2.41333 4.942 2.516C5.29667 2.60933 5.59533 2.74933 5.838 2.936C6.09 3.11333 6.28133 3.32333 6.412 3.566C6.54267 3.80867 6.608 4.07 6.608 4.35C6.608 4.41533 6.60333 4.476 6.594 4.532C6.594 4.588 6.594 4.62533 6.594 4.644H5.166V4.518C5.166 4.33133 5.11467 4.16333 5.012 4.014C4.90933 3.86467 4.746 3.74333 4.522 3.65C4.30733 3.55667 4.018 3.51 3.654 3.51C3.41133 3.51 3.19667 3.53333 3.01 3.58C2.82333 3.61733 2.66933 3.678 2.548 3.762C2.42667 3.83667 2.33333 3.92533 2.268 4.028C2.212 4.12133 2.184 4.23333 2.184 4.364C2.184 4.57867 2.25867 4.74667 2.408 4.868C2.56667 4.98 2.772 5.078 3.024 5.162C3.276 5.23667 3.54667 5.32067 3.836 5.414C4.172 5.50733 4.51267 5.60533 4.858 5.708C5.20333 5.80133 5.52067 5.92267 5.81 6.072C6.10867 6.22133 6.34667 6.43133 6.524 6.702C6.71067 6.96333 6.804 7.30867 6.804 7.738C6.804 8.14867 6.72467 8.50333 6.566 8.802C6.40733 9.09133 6.18333 9.32933 5.894 9.516C5.614 9.70267 5.28267 9.838 4.9 9.922C4.51733 10.006 4.102 10.048 3.654 10.048Z" fill="#121010"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
3
docs/_static/images/cmnd-link-icon.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.2426 9.12076L10.1821 8.06026L11.2426 6.99976C11.5212 6.72118 11.7421 6.39045 11.8929 6.02646C12.0437 5.66248 12.1213 5.27236 12.1213 4.87838C12.1213 4.48441 12.0437 4.09429 11.8929 3.7303C11.7421 3.36632 11.5212 3.03559 11.2426 2.75701C10.964 2.47843 10.6333 2.25744 10.2693 2.10667C9.9053 1.95591 9.51518 1.87831 9.1212 1.87831C8.72723 1.87831 8.33711 1.95591 7.97312 2.10667C7.60914 2.25744 7.27841 2.47843 6.99983 2.75701L5.93933 3.81751L4.87883 2.75701L5.93933 1.69651C6.78556 0.863948 7.9265 0.3995 9.11361 0.404334C10.3007 0.409168 11.4378 0.882891 12.2773 1.72232C13.1167 2.56174 13.5904 3.69886 13.5953 4.88597C13.6001 6.07309 13.1356 7.21403 12.3031 8.06026L11.2426 9.12076ZM9.12083 11.2425L8.06033 12.303C7.64372 12.7265 7.14739 13.0632 6.59998 13.2939C6.05256 13.5246 5.46489 13.6446 4.87086 13.647C4.27684 13.6494 3.68821 13.5342 3.13893 13.308C2.58966 13.0818 2.0906 12.7491 1.67056 12.329C1.25051 11.909 0.917792 11.4099 0.691584 10.8607C0.465375 10.3114 0.350158 9.72275 0.352576 9.12872C0.354995 8.5347 0.475003 7.94703 0.705677 7.39961C0.936351 6.85219 1.27313 6.35587 1.69658 5.93926L2.75708 4.87876L3.81758 5.93926L2.75708 6.99976C2.47849 7.27834 2.25751 7.60907 2.10674 7.97305C1.95597 8.33704 1.87837 8.72716 1.87837 9.12113C1.87837 9.51511 1.95597 9.90523 2.10674 10.2692C2.25751 10.6332 2.47849 10.9639 2.75708 11.2425C3.03566 11.5211 3.36639 11.7421 3.73037 11.8928C4.09436 12.0436 4.48448 12.1212 4.87845 12.1212C5.27243 12.1212 5.66255 12.0436 6.02653 11.8928C6.39052 11.7421 6.72124 11.5211 6.99983 11.2425L8.06033 10.182L9.12083 11.2425ZM9.12083 3.81751L10.1821 4.87876L4.87883 10.1813L3.81758 9.12076L9.12083 3.81751Z" fill="#8D9499"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
4
docs/_static/images/copy-code-icon.svg
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="4.95605" y="4.5" width="7" height="7" rx="1.5" stroke="#FD8F01"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.456055 2C0.456055 0.895431 1.35149 0 2.45605 0H6.45605C7.56062 0 8.45605 0.895431 8.45605 2V3H7.45605V2C7.45605 1.44772 7.00834 1 6.45605 1H2.45605C1.90377 1 1.45605 1.44772 1.45605 2V6C1.45605 6.55228 1.90377 7 2.45605 7H3.45605V8H2.45605C1.35149 8 0.456055 7.10457 0.456055 6V2Z" fill="#FD8F01"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 529 B |
BIN
docs/_static/images/firewall-bridge-packet-flow.png
vendored
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/_static/images/firewall-flowtable-packet-flow.png
vendored
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
docs/_static/images/firewall-fwd-packet-flow.png
vendored
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
docs/_static/images/firewall-gral-packet-flow.png
vendored
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
docs/_static/images/firewall-input-packet-flow.png
vendored
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
docs/_static/images/firewall-traditional.png
vendored
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/_static/images/firewall-zonebased.png
vendored
Normal file
|
After Width: | Height: | Size: 54 KiB |
10
docs/_static/images/github.svg
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="15" height="14" viewBox="0 0 15 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_17762_41)">
|
||||
<path d="M3.93172 10.8809C3.75672 10.7642 3.60622 10.6155 3.43005 10.4049C3.33861 10.293 3.248 10.1804 3.15822 10.0672C2.88813 9.73174 2.7178 9.57716 2.54163 9.51358C2.39598 9.46128 2.27706 9.35327 2.21103 9.2133C2.14501 9.07333 2.1373 8.91286 2.18959 8.7672C2.24188 8.62154 2.3499 8.50262 2.48987 8.4366C2.62984 8.37058 2.79031 8.36287 2.93597 8.41516C3.37463 8.57266 3.67155 8.84391 4.07172 9.34149C4.01688 9.27324 4.27005 9.59058 4.3243 9.65591C4.43513 9.78833 4.5168 9.86883 4.58097 9.91141C4.69997 9.99133 4.92338 10.0257 5.2518 9.99308C5.26522 9.77024 5.30663 9.55383 5.36963 9.35433C3.6383 8.93083 2.6583 7.81433 2.6583 5.62333C2.6583 4.89999 2.87413 4.24899 3.27547 3.70299C3.1483 3.18149 3.16755 2.55091 3.45163 1.84099C3.48387 1.76069 3.53358 1.68856 3.59714 1.62984C3.6607 1.57112 3.73653 1.52728 3.81913 1.50149C3.86638 1.48749 3.89322 1.48108 3.94047 1.47408C4.40888 1.40233 5.07038 1.57324 5.93255 2.11341C6.44635 1.99329 6.97232 1.933 7.49997 1.93374C8.03197 1.93374 8.56047 1.99441 9.06563 2.11341C9.92722 1.56916 10.5899 1.39824 11.0618 1.47408C11.1114 1.48166 11.1534 1.49158 11.189 1.50324C11.27 1.52995 11.3441 1.57408 11.4062 1.63253C11.4683 1.69099 11.5168 1.76235 11.5483 1.84158C11.8324 2.55091 11.8516 3.18149 11.7245 3.70241C12.1276 4.24841 12.3416 4.89533 12.3416 5.62333C12.3416 7.81491 11.3651 8.92791 9.6338 9.35199C9.70672 9.59408 9.74463 9.86474 9.74463 10.157C9.74469 10.6851 9.74235 11.2132 9.73763 11.7413C9.86864 11.7699 9.9858 11.8427 10.0694 11.9476C10.153 12.0524 10.1979 12.1828 10.1966 12.3169C10.1953 12.451 10.1479 12.5805 10.0622 12.6837C9.97663 12.7869 9.85808 12.8575 9.72655 12.8835C9.06213 13.0165 8.5698 12.5732 8.5698 11.9939L8.57097 11.7337L8.57388 11.3225C8.5768 10.9095 8.57797 10.542 8.57797 10.157C8.57797 9.75041 8.47122 9.48499 8.33005 9.36366C7.94447 9.03116 8.13988 8.39824 8.64505 8.34166C10.3758 8.14741 11.175 7.47716 11.175 5.62333C11.175 5.06624 10.993 4.60599 10.6424 4.22099C10.5685 4.14005 10.5189 4.03994 10.4993 3.93213C10.4797 3.82432 10.4909 3.71317 10.5316 3.61141C10.6284 3.36991 10.6698 3.05316 10.5876 2.66991L10.5817 2.67166C10.2953 2.75274 9.93422 2.92833 9.49788 3.22524C9.42752 3.27299 9.34758 3.30478 9.26364 3.31838C9.1797 3.33199 9.09381 3.32708 9.01197 3.30399C8.51958 3.16766 8.01088 3.09917 7.49997 3.10041C6.9808 3.10041 6.4663 3.16983 5.98797 3.30458C5.90643 3.32748 5.82088 3.33235 5.73727 3.31885C5.65366 3.30535 5.57399 3.27381 5.5038 3.22641C5.06513 2.93066 4.7023 2.75566 4.41413 2.67399C4.33013 3.05491 4.37155 3.37049 4.4678 3.61141C4.50852 3.71312 4.51978 3.82424 4.50028 3.93205C4.48078 4.03985 4.43132 4.13999 4.35755 4.22099C4.0093 4.60249 3.82497 5.07149 3.82497 5.62333C3.82497 7.47366 4.62472 8.14799 6.34613 8.34166C6.85072 8.39824 7.04672 9.02824 6.66347 9.36133C6.55147 9.45933 6.41322 9.78833 6.41322 10.157V11.9945C6.41322 12.5697 5.92613 13.0007 5.26988 12.8858C5.13675 12.8624 5.01586 12.7936 4.92789 12.6909C4.83991 12.5883 4.79031 12.4583 4.78755 12.3232C4.7848 12.188 4.82906 12.0561 4.91278 11.95C4.9965 11.8439 5.11448 11.7701 5.24655 11.7413V11.1638C4.71572 11.1994 4.27705 11.1125 3.93172 10.8809Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_17762_41">
|
||||
<rect width="14" height="14" fill="white" transform="translate(0.5)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
3
docs/_static/images/hamburger-icon.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 5.3335H24M0 12.0002H24M0 18.6668H24" stroke="#FFAE12" stroke-width="3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 188 B |
BIN
docs/_static/images/keypairs.png
vendored
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/_static/images/lac-lns-diagram.jpg
vendored
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
docs/_static/images/lac-lns-winclient.jpg
vendored
Normal file
|
After Width: | Height: | Size: 89 KiB |
5
docs/_static/images/note-icon.svg
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.58341 8.91675V7.75008H5.41675V8.91675H6.58341Z" fill="#356E81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.00008 0.166748C9.22008 0.166748 11.8334 2.78008 11.8334 6.00008C11.8334 9.22008 9.22008 11.8334 6.00008 11.8334C2.78008 11.8334 0.166748 9.22008 0.166748 6.00008C0.166748 2.78008 2.78008 0.166748 6.00008 0.166748ZM6.00008 10.6667C8.57841 10.6667 10.6667 8.57841 10.6667 6.00008C10.6667 3.42175 8.57841 1.33341 6.00008 1.33341C3.42175 1.33341 1.33341 3.42175 1.33341 6.00008C1.33341 8.57841 3.42175 10.6667 6.00008 10.6667Z" fill="#356E81"/>
|
||||
<path d="M5.41675 6.87508H6.58341V3.08341H5.41675V6.87508Z" fill="#356E81"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 750 B |
BIN
docs/_static/images/sg.png
vendored
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
docs/_static/images/traffic.png
vendored
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png
vendored
Normal file
|
After Width: | Height: | Size: 341 KiB |
67
docs/_static/js/codecopier.js
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
const hamburgerIcon = `
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 5.3335H24M0 12.0002H24M0 18.6668H24" stroke="#FFAE12" stroke-width="3"/>
|
||||
</svg>
|
||||
`
|
||||
|
||||
const innersOfCopyDiv = `
|
||||
<p>Copy</p>
|
||||
<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="4.95605" y="4.5" width="7" height="7" rx="1.5" stroke="#FD8F01"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.456055 2C0.456055 0.895431 1.35149 0 2.45605 0H6.45605C7.56062 0 8.45605 0.895431 8.45605 2V3H7.45605V2C7.45605 1.44772 7.00834 1 6.45605 1H2.45605C1.90377 1 1.45605 1.44772 1.45605 2V6C1.45605 6.55228 1.90377 7 2.45605 7H3.45605V8H2.45605C1.35149 8 0.456055 7.10457 0.456055 6V2Z" fill="#FD8F01"/>
|
||||
</svg>
|
||||
`
|
||||
|
||||
function formDiv(id) {
|
||||
return `
|
||||
<div class='copyDiv' data-identifier='${id}'>
|
||||
${innersOfCopyDiv}
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
$(document).ready(async function () {
|
||||
const codeSnippets = $(
|
||||
'.rst-content div[class^=highlight] div[class^=highlight], .rst-content pre.literal-block div[class^=highlight], .rst-content pre.literal-block div[class^=highlight]'
|
||||
)
|
||||
|
||||
codeSnippets.each((index, el) => {
|
||||
el.insertAdjacentHTML('beforeend', formDiv(index))
|
||||
})
|
||||
|
||||
const copyButton = $('.copyDiv')
|
||||
|
||||
copyButton.click(async ({
|
||||
currentTarget
|
||||
}) => {
|
||||
// we obtain text and copy it
|
||||
const id = currentTarget.dataset.identifier
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(currentTarget.offsetParent.innerText)
|
||||
} catch (error) {
|
||||
console.log('Copiing text failed, please try again', {
|
||||
error
|
||||
})
|
||||
}
|
||||
|
||||
// we edit the copyDiv connected to copied text
|
||||
const divWithNeededId = $(`div[data-identifier='${id}']`)
|
||||
divWithNeededId.addClass('copiedNotifier')
|
||||
divWithNeededId.html('<span>Copied!</span>')
|
||||
|
||||
setTimeout(() => {
|
||||
divWithNeededId.html(innersOfCopyDiv)
|
||||
divWithNeededId.removeClass('copiedNotifier')
|
||||
|
||||
}, 2000)
|
||||
})
|
||||
|
||||
// we edit the button that is added by readthedocs portal
|
||||
const readTheDocsButton = $('div.rst-versions')
|
||||
const navbar = $('nav[data-toggle=wy-nav-shift]')
|
||||
|
||||
navbar.append(readTheDocsButton)
|
||||
|
||||
});
|
||||
|
||||
92
docs/_static/js/footer.js
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
$(document).ready(function() {
|
||||
insertIframe()
|
||||
|
||||
const options = {
|
||||
threshold: 0.01,
|
||||
}
|
||||
const divDoc = document.querySelector('.iframe-container')
|
||||
const innerSidebar = $('.wy-side-scroll')
|
||||
|
||||
intersectionObserver(options, divDoc, innerSidebar)
|
||||
|
||||
$(window).resize(function() {
|
||||
intersectionObserver(options, divDoc, innerSidebar)
|
||||
})
|
||||
|
||||
$(window).scroll(function() {
|
||||
intersectionObserver(options, divDoc, innerSidebar)
|
||||
})
|
||||
});
|
||||
|
||||
function intersectionObserver(options, divDoc, innerSidebar) {
|
||||
// we delete any inline-styles from innerSidebar
|
||||
if($(innerSidebar).attr('style')) {
|
||||
innerSidebar.removeAttr('style')
|
||||
}
|
||||
const screenWidth = $(window).width()
|
||||
const sidebar = $('.wy-nav-side')
|
||||
const documentHeight = $(document).height()
|
||||
const iframeHeight = $('.iframe-container').height()
|
||||
const currentPosition = $(document).scrollTop()
|
||||
const additionalPaddingFromSidebar = screenWidth > 991 ? 70 : 83
|
||||
const heightThatIsAddedByPaddings = 36
|
||||
const resultOfSums = documentHeight -
|
||||
iframeHeight -
|
||||
currentPosition -
|
||||
additionalPaddingFromSidebar -
|
||||
heightThatIsAddedByPaddings
|
||||
const heightOfAdditionalButton = 50
|
||||
|
||||
const onEntry = (entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.isIntersecting) {
|
||||
if(resultOfSums <= 70) {
|
||||
$(sidebar).hide()
|
||||
return
|
||||
}
|
||||
$(sidebar).show()
|
||||
$(sidebar).height(resultOfSums)
|
||||
$(sidebar).css('margin-bottom', '20px')
|
||||
$(innerSidebar).removeAttr('style')
|
||||
$(innerSidebar).height(resultOfSums - heightOfAdditionalButton)
|
||||
return
|
||||
} else {
|
||||
$(sidebar).removeAttr('style')
|
||||
$(innerSidebar).removeAttr('style')
|
||||
}
|
||||
})
|
||||
}
|
||||
const observer = new IntersectionObserver(onEntry, options);
|
||||
observer.observe(divDoc)
|
||||
|
||||
if($(innerSidebar).attr('style')) {
|
||||
observer.unobserve(divDoc)
|
||||
}
|
||||
|
||||
determineHeightOfFooterContainer()
|
||||
|
||||
}
|
||||
|
||||
function determineHeightOfFooterContainer() {
|
||||
const iframeFooter= $('#vyos-footer-iframe');
|
||||
const title = window.document.getElementsByTagName('title')?.[0]?.text;
|
||||
const iframeContainer = $('.iframe-container')
|
||||
const href = window.location.href;
|
||||
|
||||
window.addEventListener('message',function(message){
|
||||
if(message.data.footerIframeHeight){
|
||||
$(iframeFooter).css('min-height', `${message.data.footerIframeHeight + 1}px`)
|
||||
$(iframeContainer).height(message.data.footerIframeHeight + 1)
|
||||
iframeFooter[0].contentWindow.postMessage({title, href},'*');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function insertIframe() {
|
||||
const body = $('.wy-body-for-nav')
|
||||
body.append(divWithIframe)
|
||||
}
|
||||
|
||||
const divWithIframe = `<div class="iframe-container">
|
||||
<iframe src='https://vyos.io/iframes/footer' id='vyos-footer-iframe'></iframe>
|
||||
</div>`
|
||||
162
docs/_static/js/sidebar.js
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
$(document).ready(function () {
|
||||
removeOverlayAndCloseSidebar()
|
||||
documentLoaded()
|
||||
|
||||
$(window).on("resize", function () {
|
||||
const screenWidth = window.innerWidth
|
||||
|
||||
if (screenWidth <= 991) return userIsInTabletScreenWidth(screenWidth)
|
||||
return removeOverlayAndButtons(screenWidth)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
function removeButtons() {
|
||||
const alreadyCreatedOpenButtonCheck = $('.openLeftSidebarMenuButton')
|
||||
const alreadyCreatedCloseButtonCheck = $('.closeButtonDivLine')
|
||||
|
||||
if(alreadyCreatedOpenButtonCheck[0]) alreadyCreatedOpenButtonCheck[0].remove()
|
||||
if(alreadyCreatedCloseButtonCheck[0]) alreadyCreatedCloseButtonCheck[0].remove()
|
||||
}
|
||||
|
||||
function documentLoaded() {
|
||||
const screenWidth = window.innerWidth
|
||||
|
||||
if (screenWidth <= 991) return userIsInTabletScreenWidth(screenWidth)
|
||||
return
|
||||
}
|
||||
|
||||
function userIsInTabletScreenWidth(screenWidth) {
|
||||
const alreadyCreatedButtonCheck = $('.openLeftSidebarMenuButton')
|
||||
if (alreadyCreatedButtonCheck[0]) return
|
||||
createOpenSidebarButton(screenWidth)
|
||||
createCloseSidebarButton(screenWidth)
|
||||
removeOverlayAndCloseSidebar()
|
||||
}
|
||||
|
||||
function createOverlay(screenWidth) {
|
||||
const contentContainer = $('.wy-nav-content')
|
||||
contentContainer.addClass('overlay')
|
||||
|
||||
const overlayDiv = `
|
||||
<div class='overlayDiv' />
|
||||
`
|
||||
|
||||
contentContainer.append(overlayDiv)
|
||||
|
||||
$('.wy-nav-content.overlay').on('click', onOverlayClickHandler)
|
||||
}
|
||||
|
||||
function onOverlayClickHandler() {
|
||||
removeOverlayAndCloseSidebar()
|
||||
}
|
||||
|
||||
function removeOverlayAndCloseSidebar() {
|
||||
const screenWidth = window.innerWidth
|
||||
|
||||
const contentContainer = $('.wy-nav-content')
|
||||
contentContainer.removeClass('overlay')
|
||||
|
||||
const overlayDiv = $('.overlayDiv')
|
||||
overlayDiv.remove()
|
||||
|
||||
const leftSidebarOpened = $('nav.wy-nav-side.shift')
|
||||
leftSidebarOpened.removeClass('shift')
|
||||
|
||||
const leftSidebar = $('nav.wy-nav-side')
|
||||
|
||||
// that's working don't touch
|
||||
if(screenWidth > 991) {
|
||||
// when user is not in tablet -> we add classes on opened sidebar and remove classes on closed sidebar
|
||||
const contentSection = $('section.wy-nav-content-wrap')
|
||||
const contentDiv = $('div.wy-nav-content')
|
||||
contentSection.addClass('wy-nav-content-wrap-opened-sidebar')
|
||||
contentDiv.addClass('wy-nav-content-opened-sidebar')
|
||||
contentSection.removeClass('wy-nav-content-wrap-closed-sidebar')
|
||||
contentDiv.removeClass('wy-nav-content-closed-sidebar')
|
||||
leftSidebar.removeClass('display_none')
|
||||
return
|
||||
}
|
||||
|
||||
if(screenWidth <= 991) {
|
||||
// I add closed classes to make contentContainer 100% width
|
||||
const contentSection = $('section.wy-nav-content-wrap')
|
||||
const contentDiv = $('div.wy-nav-content')
|
||||
contentSection.removeClass('wy-nav-content-wrap-opened-sidebar')
|
||||
contentDiv.removeClass('wy-nav-content-opened-sidebar')
|
||||
contentSection.addClass('wy-nav-content-wrap-closed-sidebar')
|
||||
contentDiv.addClass('wy-nav-content-closed-sidebar')
|
||||
leftSidebar.addClass('display_none')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createOpenSidebarButton() {
|
||||
const divToInsert = $('div[role=navigation][aria-label="Page navigation"]')
|
||||
divToInsert[0].insertAdjacentHTML('afterbegin', formOpenSidebarButton())
|
||||
|
||||
const newlyCreatedButton = $('.openLeftSidebarMenuButton')
|
||||
|
||||
newlyCreatedButton.on('click', onOpenLeftSidebarMenuButtonClickHandler)
|
||||
}
|
||||
|
||||
function onOpenLeftSidebarMenuButtonClickHandler(e) {
|
||||
e.stopPropagation()
|
||||
const leftSidebar = $('nav.wy-nav-side')
|
||||
const leftSidebarOpened = $('nav.wy-nav-side.shift')
|
||||
if(leftSidebarOpened[0]) {
|
||||
// leftSidebarOpened.removeClass('shift')
|
||||
removeOverlayAndCloseSidebar()
|
||||
}
|
||||
|
||||
createOverlay()
|
||||
if(leftSidebar.hasClass('display_none')) leftSidebar.removeClass('display_none')
|
||||
if(leftSidebar.hasClass('.additionalStylesForShift')) leftSidebar.removeClass('.additionalStylesForShift')
|
||||
// here I add classes to contentSection and contentDiv to make them margined left and remove closed classes if any
|
||||
const contentSection = $('section.wy-nav-content-wrap')
|
||||
const contentDiv = $('div.wy-nav-content')
|
||||
// contentSection.removeClass('wy-nav-content-wrap-closed-sidebar')
|
||||
// contentDiv.removeClass('wy-nav-content-closed-sidebar')
|
||||
// contentSection.addClass('wy-nav-content-wrap-opened-sidebar')
|
||||
// contentDiv.addClass('wy-nav-content-opened-sidebar')
|
||||
return leftSidebar.addClass('shift')
|
||||
}
|
||||
|
||||
function createCloseSidebarButton(screenWidth) {
|
||||
const updatedLeftSidebarScrollDiv = $('nav.wy-nav-side')
|
||||
|
||||
const alreadyCreatedButtonCheck = $('div.closeLeftSidebarMenuButton')
|
||||
if(alreadyCreatedButtonCheck[0]) return
|
||||
|
||||
updatedLeftSidebarScrollDiv[0].insertAdjacentHTML('beforeend', formCloseLeftSidebarButton())
|
||||
updatedLeftSidebarScrollDiv.addClass('additionalStylesForShift')
|
||||
|
||||
const createdCloseSidebarButton = $('.closeButtonDivLine')
|
||||
|
||||
createdCloseSidebarButton.on('click', function () {
|
||||
removeOverlayAndCloseSidebar()
|
||||
})
|
||||
}
|
||||
|
||||
function formOpenSidebarButton() {
|
||||
return `
|
||||
<div class='openLeftSidebarMenuButton'>
|
||||
${hamburgerIcon}
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
function formCloseLeftSidebarButton() {
|
||||
return `
|
||||
<div class='closeButtonDivLine'>
|
||||
<div class='closeLeftSidebarMenuButton'>
|
||||
Close
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
function removeOverlayAndButtons(screenWidth) {
|
||||
removeOverlayAndCloseSidebar()
|
||||
removeButtons()
|
||||
}
|
||||
28
docs/_templates/layout.html
vendored
@ -1,12 +1,32 @@
|
||||
{% extends "!layout.html" %}
|
||||
{%- set current_version = "1.4.x sagitta" %}
|
||||
{% block extrahead %}
|
||||
<style>#vyos-header-iframe{position:fixed;top:0;left:0;right:0;z-index:999999999;width:100%;border:none}</style>
|
||||
<style>#vyos-footer-iframe{width:100%;border:none}</style>
|
||||
<iframe src='https://vyos.io/iframes/header' id='vyos-header-iframe'></iframe>
|
||||
<script>const iframeHeader=document.getElementById('vyos-header-iframe');const postMessageToIframe=()=>{iframeHeader.contentWindow.postMessage({height:window.innerHeight,width:window.width},'*')};window.addEventListener('message',function(message){if(message.data.headerIframeHeight){iframeHeader.style.height=`${message.data.headerIframeHeight}px`;postMessageToIframe()}});window.addEventListener('resize',event=>{postMessageToIframe()})</script>
|
||||
<link href="{{ pathto("_static/css/custom.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/lists.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/hints.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/headers.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/breadcrumbs.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/linkButtons.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/text.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/leftSidebar.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/scrolls.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/tables.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/installation/running-on-bare-metal.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/code-snippets.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/separate-commands.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/configuration/index.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link href="{{ pathto("_static/css/datatables.css", True) }}" rel="stylesheet" type="text/css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/datatables.js", True) }}"></script>
|
||||
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/tables.js", True) }}"></script>
|
||||
{% endblock %}
|
||||
{% block extrabody %}
|
||||
<p class="devwarning">Warning: This is the dev version. The latest stable version is
|
||||
<a href="https://docs.vyos.io/en/equuleus/">Equuleus 1.3.x</a>.</a></p>
|
||||
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/codecopier.js", True) }}"></script>
|
||||
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/sidebar.js", True) }}"></script>
|
||||
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/footer.js", True) }}"></script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@ -156,6 +156,12 @@ can execute commands and then configure VyOS in the same script.
|
||||
The following example sets the hostname based on the instance identifier
|
||||
obtained from the EC2 metadata service.
|
||||
|
||||
Please observe that the same configuration pitfall described in :ref:`command-scripting`
|
||||
exists here when running ``configure`` in any context as without user group
|
||||
'vyattacfg' will cause the error message ``Set failed`` to appear.
|
||||
We therefore need to wrap it and have the script re-execute itself with the correct
|
||||
group permissions.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
||||
@ -166,6 +172,9 @@ obtained from the EC2 metadata service.
|
||||
permissions: '0775'
|
||||
content: |
|
||||
#!/bin/vbash
|
||||
if [ "$(id -g -n)" != 'vyattacfg' ] ; then
|
||||
exec sg vyattacfg -c "/bin/vbash $(readlink -f $0) $@"
|
||||
fi
|
||||
source /opt/vyatta/etc/functions/script-template
|
||||
hostname=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
|
||||
configure
|
||||
@ -268,7 +277,7 @@ Generate qcow image
|
||||
-------------------
|
||||
|
||||
A VyOS qcow image with cloud-init options is needed. This can be obtained
|
||||
using `vyos-vm-images`_ repo. After clonning the repo, edit the file
|
||||
using `vyos-vm-images`_ repo. After cloning the repo, edit the file
|
||||
**qemu.yml** and comment the **download-iso** role.
|
||||
|
||||
In this lab, we are using 1.3.0 VyOS version and setting a disk of 10G.
|
||||
@ -344,7 +353,7 @@ Content of network-config file:
|
||||
dhcp4: false
|
||||
dhcp6: false
|
||||
|
||||
Finaly, file **meta-data** has no content, but it's required.
|
||||
Finally, file **meta-data** has no content, but it's required.
|
||||
|
||||
---------------
|
||||
Create seed.iso
|
||||
@ -360,7 +369,7 @@ Command for generating ``seed.iso``
|
||||
mkisofs -joliet -rock -volid "cidata" -output seed.iso meta-data \
|
||||
user-data network-config
|
||||
|
||||
**NOTE**: be carefull while copying and pasting previous commands. Doble
|
||||
**NOTE**: be careful while copying and pasting previous commands. Double
|
||||
quotes may need to be corrected.
|
||||
|
||||
---------------
|
||||
|
||||
@ -49,7 +49,7 @@ prepended with ``run``, even if you haven't created a session with configure.
|
||||
Run commands remotely
|
||||
---------------------
|
||||
|
||||
Sometimes you simply wan't to execute a bunch of op-mode commands via SSH on
|
||||
Sometimes you simply want to execute a bunch of op-mode commands via SSH on
|
||||
a remote VyOS system.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
@ -2,18 +2,15 @@
|
||||
VyOS Automation
|
||||
###############
|
||||
|
||||
|
||||
* Nornir
|
||||
* startup scripts
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
|
||||
vyos-api
|
||||
vyos-ansible
|
||||
terraform/index
|
||||
vyos-napalm
|
||||
vyos-netmiko
|
||||
vyos-salt
|
||||
command-scripting
|
||||
cloud-init
|
||||
|
||||
|
||||
14
docs/automation/terraform/index.rst
Normal file
@ -0,0 +1,14 @@
|
||||
##############
|
||||
VyOS Terraform
|
||||
##############
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Content
|
||||
|
||||
terraformvyos
|
||||
terraformAWS
|
||||
terraformAZ
|
||||
terraformvSphere
|
||||
terraformGoogle
|
||||
|
||||
547
docs/automation/terraform/terraformAWS.rst
Normal file
@ -0,0 +1,547 @@
|
||||
:lastproofread: 2024-01-11
|
||||
|
||||
.. _terraformAWS:
|
||||
|
||||
Deploying VyOS in the AWS cloud
|
||||
===============================
|
||||
|
||||
With the help of Terraform, you can quickly deploy VyOS-based infrastructure in the AWS cloud. If necessary, the infrastructure can be removed using terraform.
|
||||
Also we will make provisioning using Ansible.
|
||||
|
||||
|
||||
.. image:: /_static/images/aws.png
|
||||
:width: 50%
|
||||
:align: center
|
||||
:alt: Network Topology Diagram
|
||||
|
||||
In this case, we'll create the necessary files for Terraform and Ansible next using Terraform we'll create a single instance on the AWS cloud and make provisioning using Ansible.
|
||||
|
||||
|
||||
Preparation steps for deploying VyOS on AWS
|
||||
-------------------------------------------
|
||||
|
||||
How to create a single instance and install your configuration using Terraform+Ansible+AWS
|
||||
Step by step:
|
||||
|
||||
AWS
|
||||
|
||||
|
||||
1 Create an account with AWS and get your "access_key", "secret key"
|
||||
|
||||
2 Create a key pair_ and download your .pem key
|
||||
|
||||
.. image:: /_static/images/keypairs.png
|
||||
:width: 50%
|
||||
:align: center
|
||||
:alt: Network Topology Diagram
|
||||
|
||||
3 Create a security group_ for the new VyOS instance and open all traffic
|
||||
|
||||
.. image:: /_static/images/sg.png
|
||||
:width: 50%
|
||||
:align: center
|
||||
:alt: Network Topology Diagram
|
||||
|
||||
|
||||
.. image:: /_static/images/traffic.png
|
||||
:width: 50%
|
||||
:align: center
|
||||
:alt: Network Topology Diagram
|
||||
|
||||
Terraform
|
||||
|
||||
|
||||
1 Create an UNIX or Windows instance
|
||||
|
||||
2 Download and install Terraform
|
||||
|
||||
3 Create the folder for example /root/awsterraform
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
mkdir /root/awsterraform
|
||||
|
||||
4 Copy all files into your Terraform project "/root/awsterraform" (vyos.tf, var.tf, terraform.tfvars,version.tf), more detailed see `Structure of files Terrafom for AWS`_
|
||||
|
||||
5 Type the commands :
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder>
|
||||
terraform init
|
||||
|
||||
|
||||
Ansible
|
||||
|
||||
|
||||
1 Create an UNIX instance whenever you want (local, cloud, and so on)
|
||||
|
||||
2 Download and install Ansible
|
||||
|
||||
3 Create the folder for example /root/aws/
|
||||
|
||||
4 Copy all files into your Ansible project "/root/aws/" (ansible.cfg, instance.yml, mykey.pem and "all"), more detailed see `Structure of files Ansible for AWS`_
|
||||
|
||||
mykey.pem you have to get using step 1.2
|
||||
|
||||
|
||||
Start
|
||||
|
||||
|
||||
Type the commands on your Terrafom instance:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder>
|
||||
terraform plan
|
||||
terraform apply
|
||||
yes
|
||||
|
||||
|
||||
Start creating an AWS instance and check the result
|
||||
---------------------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
root@localhost:~/awsterraform# terraform apply
|
||||
|
||||
Terraform used the selected providers to generate the following execution plan.
|
||||
Resource actions are indicated with the following symbols:
|
||||
+ create
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# aws_instance.myVyOSec2 will be created
|
||||
+ resource "aws_instance" "myVyOSec2" {
|
||||
+ ami = "ami-************62c2d"
|
||||
+ arn = (known after apply)
|
||||
+ associate_public_ip_address = (known after apply)
|
||||
+ availability_zone = (known after apply)
|
||||
+ cpu_core_count = (known after apply)
|
||||
+ cpu_threads_per_core = (known after apply)
|
||||
+ disable_api_stop = (known after apply)
|
||||
+ disable_api_termination = (known after apply)
|
||||
+ ebs_optimized = (known after apply)
|
||||
+ get_password_data = false
|
||||
+ host_id = (known after apply)
|
||||
+ host_resource_group_arn = (known after apply)
|
||||
+ iam_instance_profile = (known after apply)
|
||||
+ id = (known after apply)
|
||||
+ instance_initiated_shutdown_behavior = (known after apply)
|
||||
+ instance_lifecycle = (known after apply)
|
||||
+ instance_state = (known after apply)
|
||||
+ instance_type = "t2.micro"
|
||||
+ ipv6_address_count = (known after apply)
|
||||
+ ipv6_addresses = (known after apply)
|
||||
+ key_name = "awsterraform"
|
||||
+ monitoring = (known after apply)
|
||||
+ outpost_arn = (known after apply)
|
||||
+ password_data = (known after apply)
|
||||
+ placement_group = (known after apply)
|
||||
+ placement_partition_number = (known after apply)
|
||||
+ primary_network_interface_id = (known after apply)
|
||||
+ private_dns = (known after apply)
|
||||
+ private_ip = (known after apply)
|
||||
+ public_dns = (known after apply)
|
||||
+ public_ip = (known after apply)
|
||||
+ secondary_private_ips = (known after apply)
|
||||
+ security_groups = [
|
||||
+ "awsterraformsg",
|
||||
]
|
||||
+ source_dest_check = true
|
||||
+ spot_instance_request_id = (known after apply)
|
||||
+ subnet_id = (known after apply)
|
||||
+ tags = {
|
||||
+ "name" = "VyOS System"
|
||||
}
|
||||
+ tags_all = {
|
||||
+ "name" = "VyOS System"
|
||||
}
|
||||
+ tenancy = (known after apply)
|
||||
+ user_data = (known after apply)
|
||||
+ user_data_base64 = (known after apply)
|
||||
+ user_data_replace_on_change = false
|
||||
+ vpc_security_group_ids = (known after apply)
|
||||
}
|
||||
|
||||
# local_file.ip will be created
|
||||
+ resource "local_file" "ip" {
|
||||
+ content = (known after apply)
|
||||
+ content_base64sha256 = (known after apply)
|
||||
+ content_base64sha512 = (known after apply)
|
||||
+ content_md5 = (known after apply)
|
||||
+ content_sha1 = (known after apply)
|
||||
+ content_sha256 = (known after apply)
|
||||
+ content_sha512 = (known after apply)
|
||||
+ directory_permission = "0777"
|
||||
+ file_permission = "0777"
|
||||
+ filename = "ip.txt"
|
||||
+ id = (known after apply)
|
||||
}
|
||||
|
||||
# null_resource.SSHconnection1 will be created
|
||||
+ resource "null_resource" "SSHconnection1" {
|
||||
+ id = (known after apply)
|
||||
}
|
||||
|
||||
# null_resource.SSHconnection2 will be created
|
||||
+ resource "null_resource" "SSHconnection2" {
|
||||
+ id = (known after apply)
|
||||
}
|
||||
|
||||
Plan: 4 to add, 0 to change, 0 to destroy.
|
||||
|
||||
Changes to Outputs:
|
||||
+ my_IP = (known after apply)
|
||||
|
||||
Do you want to perform these actions?
|
||||
Terraform will perform the actions described above.
|
||||
Only 'yes' will be accepted to approve.
|
||||
|
||||
Enter a value: yes
|
||||
|
||||
aws_instance.myVyOSec2: Creating...
|
||||
aws_instance.myVyOSec2: Still creating... [10s elapsed]
|
||||
aws_instance.myVyOSec2: Still creating... [20s elapsed]
|
||||
aws_instance.myVyOSec2: Still creating... [30s elapsed]
|
||||
aws_instance.myVyOSec2: Still creating... [40s elapsed]
|
||||
aws_instance.myVyOSec2: Creation complete after 44s [id=i-09edfca15aac2fe0a]
|
||||
null_resource.SSHconnection1: Creating...
|
||||
null_resource.SSHconnection2: Creating...
|
||||
null_resource.SSHconnection1: Provisioning with 'file'...
|
||||
null_resource.SSHconnection2: Provisioning with 'remote-exec'...
|
||||
null_resource.SSHconnection2 (remote-exec): Connecting to remote host via SSH...
|
||||
null_resource.SSHconnection2 (remote-exec): Host: 10.217.80.104
|
||||
null_resource.SSHconnection2 (remote-exec): User: root
|
||||
null_resource.SSHconnection2 (remote-exec): Password: true
|
||||
null_resource.SSHconnection2 (remote-exec): Private key: false
|
||||
null_resource.SSHconnection2 (remote-exec): Certificate: false
|
||||
null_resource.SSHconnection2 (remote-exec): SSH Agent: false
|
||||
null_resource.SSHconnection2 (remote-exec): Checking Host Key: false
|
||||
null_resource.SSHconnection2 (remote-exec): Target Platform: unix
|
||||
local_file.ip: Creating...
|
||||
local_file.ip: Creation complete after 0s [id=e8e91f2e24579cd28b92e2d152c0c24c3bf4b52c]
|
||||
null_resource.SSHconnection2 (remote-exec): Connected!
|
||||
null_resource.SSHconnection1: Creation complete after 0s [id=7070868940858935600]
|
||||
|
||||
null_resource.SSHconnection2 (remote-exec): PLAY [integration of terraform and ansible] ************************************
|
||||
|
||||
null_resource.SSHconnection2 (remote-exec): TASK [Wait 300 seconds, but only start checking after 60 seconds] **************
|
||||
null_resource.SSHconnection2: Still creating... [10s elapsed]
|
||||
null_resource.SSHconnection2: Still creating... [20s elapsed]
|
||||
null_resource.SSHconnection2: Still creating... [30s elapsed]
|
||||
null_resource.SSHconnection2: Still creating... [40s elapsed]
|
||||
null_resource.SSHconnection2: Still creating... [50s elapsed]
|
||||
null_resource.SSHconnection2: Still creating... [1m0s elapsed]
|
||||
null_resource.SSHconnection2 (remote-exec): ok: [54.xxx.xxx.xxx]
|
||||
|
||||
null_resource.SSHconnection2 (remote-exec): TASK [Configure general settings for the vyos hosts group] *********************
|
||||
null_resource.SSHconnection2: Still creating... [1m10s elapsed]
|
||||
null_resource.SSHconnection2 (remote-exec): changed: [54.xxx.xxx.xxx]
|
||||
|
||||
null_resource.SSHconnection2 (remote-exec): PLAY RECAP *********************************************************************
|
||||
null_resource.SSHconnection2 (remote-exec): 54.xxx.xxx.xxx : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
|
||||
null_resource.SSHconnection2: Creation complete after 1m16s [id=4902256962410024771]
|
||||
|
||||
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
|
||||
|
||||
Outputs:
|
||||
|
||||
my_IP = "54.xxx.xxx.xxx"
|
||||
|
||||
|
||||
|
||||
After executing all the commands you will have your VyOS instance on the AWS cloud with your configuration, it's a very convenient desition.
|
||||
If you need to delete the instance please type the command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
terraform destroy
|
||||
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
1 Ansible doesn't connect via SSH to your AWS instance: you have to check that your SSH key has copied into the path /root/aws/.
|
||||
Also, increase the time in the file instance.yml from 300 sec to 500 sec or more. (It depends on your location).
|
||||
Make sure that you have opened access to the instance in the security group.
|
||||
|
||||
2 Terraform doesn't connect via SSH to your Ansible instance: you have to check the correct login and password in the part of the file VyOS. tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root" # open root access using login and password on your Ansible
|
||||
password = var.password # check password in the file terraform.tfvars isn't empty
|
||||
host = var.host # check the correct IP address of your Ansible host
|
||||
}
|
||||
|
||||
|
||||
Make sure that Ansible is pinging from Terrafom.
|
||||
|
||||
Structure of files Terrafom for AWS
|
||||
-----------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── vyos.tf # The main script
|
||||
├── var.tf # The file of all variables in "vyos.tf"
|
||||
├── versions.tf # File for the changing version of Terraform.
|
||||
└── terraform.tfvars # The value of all variables (passwords, login, ip adresses and so on)
|
||||
|
||||
|
||||
|
||||
File contents of Terrafom for AWS
|
||||
---------------------------------
|
||||
|
||||
vyos.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Build an VyOS VM from the Marketplace
|
||||
# To finde nessesery AMI image_ in AWS
|
||||
#
|
||||
# In the script vyos.tf we'll use default values (you can chang it as you need)
|
||||
# AWS Region = "us-east-1"
|
||||
# AMI = "standard AMI of VyOS from AWS Marketplace"
|
||||
# Size of VM = "t2.micro"
|
||||
# AWS Region = "us-east-1"
|
||||
# After deploying the AWS instance and getting an IP address, the IP address is copied into the file
|
||||
#"ip.txt" and copied to the Ansible node for provisioning.
|
||||
##############################################################################
|
||||
|
||||
provider "aws" {
|
||||
access_key = var.access
|
||||
secret_key = var.secret
|
||||
region = var.region
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
default = "us-east-1"
|
||||
description = "AWS Region"
|
||||
}
|
||||
|
||||
variable "ami" {
|
||||
default = "ami-**************3b3" # ami image please enter your details
|
||||
description = "Amazon Machine Image ID for VyOS"
|
||||
}
|
||||
|
||||
variable "type" {
|
||||
default = "t2.micro"
|
||||
description = "Size of VM"
|
||||
}
|
||||
|
||||
# my resource for VyOS
|
||||
|
||||
resource "aws_instance" "myVyOSec2" {
|
||||
ami = var.ami
|
||||
key_name = "awsterraform" # Please enter your details from 1.2 of Preparation steps for deploying VyOS on AWS
|
||||
security_groups = ["awsterraformsg"] # Please enter your details from 1.3 of Preparation steps for deploying VyOS on AWS
|
||||
instance_type = var.type
|
||||
tags = {
|
||||
name = "VyOS System"
|
||||
}
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# specific variable (to getting type "terraform plan"):
|
||||
# aws_instance.myVyOSec2.public_ip - the information about public IP address
|
||||
# of our instance, needs for provisioning and ssh connection from Ansible
|
||||
##############################################################################
|
||||
|
||||
output "my_IP"{
|
||||
value = aws_instance.myVyOSec2.public_ip
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# IP of aws instance copied to a file ip.txt in local system Terraform
|
||||
# ip.txt looks like:
|
||||
# cat ./ip.txt
|
||||
# ххх.ххх.ххх.ххх
|
||||
##############################################################################
|
||||
|
||||
resource "local_file" "ip" {
|
||||
content = aws_instance.myVyOSec2.public_ip
|
||||
filename = "ip.txt"
|
||||
}
|
||||
|
||||
#connecting to the Ansible control node using SSH connection
|
||||
|
||||
##############################################################################
|
||||
# Steps "SSHconnection1" and "SSHconnection2" need to get file ip.txt from the terraform node and start remotely the playbook of Ansible.
|
||||
##############################################################################
|
||||
|
||||
resource "null_resource" "SSHconnection1" {
|
||||
depends_on = [aws_instance.myVyOSec2]
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
password = var.password
|
||||
host = var.host
|
||||
}
|
||||
|
||||
#copying the ip.txt file to the Ansible control node from local system
|
||||
|
||||
provisioner "file" {
|
||||
source = "ip.txt"
|
||||
destination = "/root/aws/ip.txt" # The folder of your Ansible project
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "SSHconnection2" {
|
||||
depends_on = [aws_instance.myVyOSec2]
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
password = var.password
|
||||
host = var.host
|
||||
}
|
||||
#command to run Ansible playbook on remote Linux OS
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"cd /root/aws/",
|
||||
"ansible-playbook instance.yml" # more detailed in "File contents of Ansible for AWS"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
variable "password" {
|
||||
description = "pass for Ansible"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "host"{
|
||||
description = "The IP of my Ansible"
|
||||
type = string
|
||||
}
|
||||
variable "access" {
|
||||
description = "my access_key for AWS"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "secret" {
|
||||
description = "my secret_key for AWS"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
versions.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
terraform.tfvars
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
password = "" # password for Ansible SSH
|
||||
host = "" # IP of my Ansible
|
||||
access = "" # access_key for AWS
|
||||
secret = "" # secret_key for AWS
|
||||
|
||||
|
||||
Structure of files Ansible for AWS
|
||||
----------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── group_vars
|
||||
└── all
|
||||
├── ansible.cfg
|
||||
├── mykey.pem
|
||||
└── instance.yml
|
||||
|
||||
|
||||
File contents of Ansible for AWS
|
||||
--------------------------------
|
||||
|
||||
ansible.cfg
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[defaults]
|
||||
inventory = /root/aws/ip.txt
|
||||
host_key_checking= False
|
||||
private_key_file = /root/aws/awsterraform.pem # check the name
|
||||
remote_user=vyos
|
||||
|
||||
mykey.pem
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Copy your key.pem from AWS
|
||||
|
||||
|
||||
instance.yml
|
||||
|
||||
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
##############################################################################
|
||||
# About tasks:
|
||||
# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds
|
||||
# "Configure general settings for the VyOS hosts group" - make provisioning into AWS VyOS node
|
||||
# You have to add all necessary cammans of VyOS under the block "lines:"
|
||||
##############################################################################
|
||||
|
||||
|
||||
- name: integration of terraform and ansible
|
||||
hosts: all
|
||||
gather_facts: 'no'
|
||||
|
||||
tasks:
|
||||
|
||||
- name: "Wait 300 seconds, but only start checking after 60 seconds"
|
||||
wait_for_connection:
|
||||
delay: 60
|
||||
timeout: 300
|
||||
|
||||
- name: "Configure general settings for the VyOS hosts group"
|
||||
vyos_config:
|
||||
lines:
|
||||
- set system name-server xxx.xxx.xxx.xxx
|
||||
save:
|
||||
true
|
||||
|
||||
|
||||
group_vars/all
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ansible_connection: ansible.netcommon.network_cli
|
||||
ansible_network_os: vyos.vyos.vyos
|
||||
ansible_user: vyos
|
||||
|
||||
Sourse files for AWS from GIT
|
||||
-----------------------------
|
||||
|
||||
All files about the article can be found here_
|
||||
|
||||
|
||||
.. _link: https://developer.hashicorp.com/terraform/intro
|
||||
.. _install: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
|
||||
.. _pair: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html
|
||||
.. _group: https://docs.aws.amazon.com/cli/latest/userguide/cli-services-ec2-sg.html
|
||||
.. _image: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html
|
||||
.. _here: https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/AWS_terraform_ansible_single_vyos_instance-main
|
||||
488
docs/automation/terraform/terraformAZ.rst
Normal file
@ -0,0 +1,488 @@
|
||||
:lastproofread: 2024-03-03
|
||||
|
||||
.. _terraformAZ:
|
||||
|
||||
Deploying VyOS in the Azure cloud
|
||||
=================================
|
||||
|
||||
With the help of Terraform, you can quickly deploy VyOS-based infrastructure in the Azure cloud. If necessary, the infrastructure can be removed using terraform.
|
||||
Also we will make provisioning using Ansible.
|
||||
|
||||
In this case, we'll create the necessary files for Terraform and Ansible next using Terraform we'll create a single instance on the Azure cloud and make provisioning using Ansible.
|
||||
|
||||
Preparation steps for deploying VyOS on Azure
|
||||
---------------------------------------------
|
||||
|
||||
How to create a single instance and install your configuration using Terraform+Ansible+Azure
|
||||
Step by step:
|
||||
|
||||
Azure
|
||||
|
||||
1 Create an account with Azure
|
||||
|
||||
Terraform
|
||||
|
||||
|
||||
1 Create an UNIX or Windows instance
|
||||
|
||||
2 Download and install Terraform
|
||||
|
||||
3 Create the folder for example /root/azvyos/
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
mkdir /root/azvyos
|
||||
|
||||
4 Copy all files into your Terraform project "/root/azvyos" (vyos.tf, var.tf, terraform.tfvars), more detailed see `Structure of files Terrafom for Azure`_
|
||||
|
||||
5 Login with Azure using the command
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
az login
|
||||
|
||||
2.6 Type the commands :
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder>
|
||||
terraform init
|
||||
|
||||
Ansible
|
||||
|
||||
|
||||
1 Create an UNIX instance whenever you want (local, cloud, and so on)
|
||||
|
||||
2 Download and install Ansible
|
||||
|
||||
3 Create the folder for example /root/az/
|
||||
|
||||
4 Copy all files into your Ansible project "/root/az/" (ansible.cfg, instance.yml,"all"), more detailed see `Structure of files Ansible for Azure`_
|
||||
|
||||
|
||||
Start
|
||||
|
||||
|
||||
Type the commands on your Terrafom instance:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder>
|
||||
terraform plan
|
||||
terraform apply
|
||||
yes
|
||||
|
||||
After executing all the commands you will have your VyOS instance on the Azure cloud with your configuration, it's a very convenient desition.
|
||||
If you need to delete the instance please type the command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
terraform destroy
|
||||
|
||||
Structure of files Terrafom for Azure
|
||||
-------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── vyos.tf # The main script
|
||||
├── var.tf # File for the changing version of Terraform.
|
||||
└── terraform.tfvars # The value of all variables (passwords, login, ip adresses and so on)
|
||||
|
||||
File contents of Terrafom for Azure
|
||||
-----------------------------------
|
||||
|
||||
vyos.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
||||
##############################################################################
|
||||
# HashiCorp Guide to Using Terraform on Azure
|
||||
# This Terraform configuration will create the following:
|
||||
# Resource group with a virtual network and subnet
|
||||
# An VyOS server without ssh key (only login+password)
|
||||
##############################################################################
|
||||
|
||||
# Chouse a provider
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
# Create a resource group. In Azure every resource belongs to a
|
||||
# resource group.
|
||||
|
||||
resource "azurerm_resource_group" "azure_vyos" {
|
||||
name = "${var.resource_group}"
|
||||
location = "${var.location}"
|
||||
}
|
||||
|
||||
# The next resource is a Virtual Network.
|
||||
|
||||
resource "azurerm_virtual_network" "vnet" {
|
||||
name = "${var.virtual_network_name}"
|
||||
location = "${var.location}"
|
||||
address_space = ["${var.address_space}"]
|
||||
resource_group_name = "${var.resource_group}"
|
||||
}
|
||||
|
||||
# Build a subnet to run our VMs in.
|
||||
|
||||
resource "azurerm_subnet" "subnet" {
|
||||
name = "${var.prefix}subnet"
|
||||
virtual_network_name = "${azurerm_virtual_network.vnet.name}"
|
||||
resource_group_name = "${var.resource_group}"
|
||||
address_prefixes = ["${var.subnet_prefix}"]
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# Build an VyOS VM from the Marketplace
|
||||
# To finde nessesery image use the command:
|
||||
#
|
||||
# az vm image list --offer vyos --all
|
||||
#
|
||||
# Now that we have a network, we'll deploy an VyOS server.
|
||||
# An Azure Virtual Machine has several components. In this example we'll build
|
||||
# a security group, a network interface, a public ip address, a storage
|
||||
# account and finally the VM itself. Terraform handles all the dependencies
|
||||
# automatically, and each resource is named with user-defined variables.
|
||||
##############################################################################
|
||||
|
||||
|
||||
# Security group to allow inbound access on port 22 (ssh)
|
||||
|
||||
resource "azurerm_network_security_group" "vyos-sg" {
|
||||
name = "${var.prefix}-sg"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group}"
|
||||
|
||||
security_rule {
|
||||
name = "SSH"
|
||||
priority = 100
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "Tcp"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
source_address_prefix = "${var.source_network}"
|
||||
destination_address_prefix = "*"
|
||||
}
|
||||
}
|
||||
|
||||
# A network interface.
|
||||
|
||||
resource "azurerm_network_interface" "vyos-nic" {
|
||||
name = "${var.prefix}vyos-nic"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group}"
|
||||
|
||||
ip_configuration {
|
||||
name = "${var.prefix}ipconfig"
|
||||
subnet_id = "${azurerm_subnet.subnet.id}"
|
||||
private_ip_address_allocation = "Dynamic"
|
||||
public_ip_address_id = "${azurerm_public_ip.vyos-pip.id}"
|
||||
}
|
||||
}
|
||||
|
||||
# Add a public IP address.
|
||||
|
||||
resource "azurerm_public_ip" "vyos-pip" {
|
||||
name = "${var.prefix}-ip"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group}"
|
||||
allocation_method = "Dynamic"
|
||||
}
|
||||
|
||||
# Build a virtual machine. This is a standard VyOS instance from Marketplace.
|
||||
|
||||
resource "azurerm_virtual_machine" "vyos" {
|
||||
name = "${var.hostname}-vyos"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group}"
|
||||
vm_size = "${var.vm_size}"
|
||||
|
||||
network_interface_ids = ["${azurerm_network_interface.vyos-nic.id}"]
|
||||
delete_os_disk_on_termination = "true"
|
||||
|
||||
# To finde an information about the plan use the command:
|
||||
# az vm image list --offer vyos --all
|
||||
|
||||
plan {
|
||||
publisher = "sentriumsl"
|
||||
name = "vyos-1-3"
|
||||
product = "vyos-1-2-lts-on-azure"
|
||||
}
|
||||
|
||||
storage_image_reference {
|
||||
publisher = "${var.image_publisher}"
|
||||
offer = "${var.image_offer}"
|
||||
sku = "${var.image_sku}"
|
||||
version = "${var.image_version}"
|
||||
}
|
||||
|
||||
storage_os_disk {
|
||||
name = "${var.hostname}-osdisk"
|
||||
managed_disk_type = "Standard_LRS"
|
||||
caching = "ReadWrite"
|
||||
create_option = "FromImage"
|
||||
}
|
||||
|
||||
os_profile {
|
||||
computer_name = "${var.hostname}"
|
||||
admin_username = "${var.admin_username}"
|
||||
admin_password = "${var.admin_password}"
|
||||
}
|
||||
|
||||
os_profile_linux_config {
|
||||
disable_password_authentication = false
|
||||
}
|
||||
}
|
||||
|
||||
data "azurerm_public_ip" "example" {
|
||||
depends_on = ["azurerm_virtual_machine.vyos"]
|
||||
name = "vyos-ip"
|
||||
resource_group_name = "${var.resource_group}"
|
||||
}
|
||||
output "public_ip_address" {
|
||||
value = data.azurerm_public_ip.example.ip_address
|
||||
}
|
||||
|
||||
# IP of AZ instance copied to a file ip.txt in local system
|
||||
|
||||
resource "local_file" "ip" {
|
||||
content = data.azurerm_public_ip.example.ip_address
|
||||
filename = "ip.txt"
|
||||
}
|
||||
|
||||
#Connecting to the Ansible control node using SSH connection
|
||||
|
||||
resource "null_resource" "nullremote1" {
|
||||
depends_on = ["azurerm_virtual_machine.vyos"]
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
password = var.password
|
||||
host = var.host
|
||||
}
|
||||
|
||||
# Copying the ip.txt file to the Ansible control node from local system
|
||||
|
||||
provisioner "file" {
|
||||
source = "ip.txt"
|
||||
destination = "/root/az/ip.txt"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "nullremote2" {
|
||||
depends_on = ["azurerm_virtual_machine.vyos"]
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
password = var.password
|
||||
host = var.host
|
||||
}
|
||||
|
||||
# Command to run ansible playbook on remote Linux OS
|
||||
|
||||
provisioner "remote-exec" {
|
||||
|
||||
inline = [
|
||||
"cd /root/az/",
|
||||
"ansible-playbook instance.yml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
##############################################################################
|
||||
# Variables File
|
||||
#
|
||||
# Here is where we store the default values for all the variables used in our
|
||||
# Terraform code.
|
||||
##############################################################################
|
||||
|
||||
variable "resource_group" {
|
||||
description = "The name of your Azure Resource Group."
|
||||
default = "my_resource_group"
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "This prefix will be included in the name of some resources."
|
||||
default = "vyos"
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Virtual machine hostname. Used for local hostname, DNS, and storage-related names."
|
||||
default = "vyos_terraform"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
description = "The region where the virtual network is created."
|
||||
default = "centralus"
|
||||
}
|
||||
|
||||
variable "virtual_network_name" {
|
||||
description = "The name for your virtual network."
|
||||
default = "vnet"
|
||||
}
|
||||
|
||||
variable "address_space" {
|
||||
description = "The address space that is used by the virtual network. You can supply more than one address space. Changing this forces a new resource to be created."
|
||||
default = "10.0.0.0/16"
|
||||
}
|
||||
|
||||
variable "subnet_prefix" {
|
||||
description = "The address prefix to use for the subnet."
|
||||
default = "10.0.10.0/24"
|
||||
}
|
||||
|
||||
variable "storage_account_tier" {
|
||||
description = "Defines the storage tier. Valid options are Standard and Premium."
|
||||
default = "Standard"
|
||||
}
|
||||
|
||||
variable "storage_replication_type" {
|
||||
description = "Defines the replication type to use for this storage account. Valid options include LRS, GRS etc."
|
||||
default = "LRS"
|
||||
}
|
||||
|
||||
# The most chippers size
|
||||
|
||||
variable "vm_size" {
|
||||
description = "Specifies the size of the virtual machine."
|
||||
default = "Standard_B1s"
|
||||
}
|
||||
|
||||
variable "image_publisher" {
|
||||
description = "Name of the publisher of the image (az vm image list)"
|
||||
default = "sentriumsl"
|
||||
}
|
||||
|
||||
variable "image_offer" {
|
||||
description = "Name of the offer (az vm image list)"
|
||||
default = "vyos-1-2-lts-on-azure"
|
||||
}
|
||||
|
||||
variable "image_sku" {
|
||||
description = "Image SKU to apply (az vm image list)"
|
||||
default = "vyos-1-3"
|
||||
}
|
||||
|
||||
variable "image_version" {
|
||||
description = "Version of the image to apply (az vm image list)"
|
||||
default = "1.3.3"
|
||||
}
|
||||
|
||||
variable "admin_username" {
|
||||
description = "Administrator user name"
|
||||
default = "vyos"
|
||||
}
|
||||
|
||||
variable "admin_password" {
|
||||
description = "Administrator password"
|
||||
default = "Vyos0!"
|
||||
}
|
||||
|
||||
variable "source_network" {
|
||||
description = "Allow access from this network prefix. Defaults to '*'."
|
||||
default = "*"
|
||||
}
|
||||
|
||||
variable "password" {
|
||||
description = "pass for Ansible"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "host"{
|
||||
description = "IP of my Ansible"
|
||||
}
|
||||
|
||||
terraform.tfvars
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
password = "" # password for Ansible SSH
|
||||
host = "" # IP of my Ansible
|
||||
|
||||
|
||||
Structure of files Ansible for Azure
|
||||
------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── group_vars
|
||||
└── all
|
||||
├── ansible.cfg
|
||||
└── instance.yml
|
||||
|
||||
|
||||
File contents of Ansible for Azure
|
||||
----------------------------------
|
||||
|
||||
ansible.cfg
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[defaults]
|
||||
inventory = /root/az/ip.txt
|
||||
host_key_checking= False
|
||||
remote_user=vyos
|
||||
|
||||
|
||||
instance.yml
|
||||
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
##############################################################################
|
||||
# About tasks:
|
||||
# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds
|
||||
# "Configure general settings for the VyOS hosts group" - make provisioning into Azure VyOS node
|
||||
# You have to add all necessary cammans of VyOS under the block "lines:"
|
||||
##############################################################################
|
||||
|
||||
|
||||
- name: integration of terraform and ansible
|
||||
hosts: all
|
||||
gather_facts: 'no'
|
||||
|
||||
tasks:
|
||||
|
||||
- name: "Wait 300 seconds, but only start checking after 60 seconds"
|
||||
wait_for_connection:
|
||||
delay: 60
|
||||
timeout: 300
|
||||
|
||||
- name: "Configure general settings for the VyOS hosts group"
|
||||
vyos_config:
|
||||
lines:
|
||||
- set system name-server xxx.xxx.xxx.xxx
|
||||
save:
|
||||
true
|
||||
|
||||
|
||||
group_vars/all
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ansible_connection: ansible.netcommon.network_cli
|
||||
ansible_network_os: vyos.vyos.vyos
|
||||
|
||||
# user and password gets from terraform variables "admin_username" and "admin_password" in the file /root/azvyos/var.tf
|
||||
ansible_user: vyos
|
||||
ansible_ssh_pass: Vyos0!
|
||||
|
||||
Sourse files for Azure from GIT
|
||||
-------------------------------
|
||||
|
||||
All files about the article can be found here_
|
||||
|
||||
.. _here: https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Azure_terraform_ansible_single_vyos_instance-main
|
||||
|
||||
|
||||
0
docs/automation/terraform/terraformGoogle.rst
Normal file
400
docs/automation/terraform/terraformvSphere.rst
Normal file
@ -0,0 +1,400 @@
|
||||
:lastproofread: 2024-03-03
|
||||
|
||||
.. _terraformvSphere:
|
||||
|
||||
Deploying VyOS in the vSphere infrastructure
|
||||
============================================
|
||||
|
||||
With the help of Terraform, you can quickly deploy VyOS-based infrastructure in the vSphere.
|
||||
Also we will make provisioning using Ansible.
|
||||
|
||||
In this case, we'll create the necessary files for Terraform and Ansible next using Terraform we'll create a single instance on the vSphere cloud and make provisioning using Ansible.
|
||||
|
||||
Preparation steps for deploying VyOS on vSphere
|
||||
-----------------------------------------------
|
||||
|
||||
How to create a single instance and install your configuration using Terraform+Ansible+vSphere
|
||||
Step by step:
|
||||
|
||||
|
||||
vSphere
|
||||
|
||||
|
||||
1 Collect all data in to file "terraform.tfvars" and create resources for example "terraform"
|
||||
|
||||
|
||||
Terraform
|
||||
|
||||
|
||||
1 Create an UNIX or Windows instance
|
||||
|
||||
2 Download and install Terraform
|
||||
|
||||
3 Create the folder for example /root/vsphereterraform
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
mkdir /root/vsphereterraform
|
||||
|
||||
|
||||
4 Copy all files into your Terraform project "/root/vsphereterraform" (vyos.tf, var.tf, terraform.tfvars,version.tf), more detailed see `Structure of files Terrafom for vSphere`_
|
||||
|
||||
5 Type the commands :
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder>
|
||||
terraform init
|
||||
|
||||
|
||||
Ansible
|
||||
|
||||
|
||||
1 Create an UNIX instance whenever you want (local, cloud, and so on)
|
||||
|
||||
2 Download and install Ansible
|
||||
|
||||
3 Create the folder for example /root/vsphereterraform/
|
||||
|
||||
4 Copy all files into your Ansible project "/root/vsphereterraform/" (ansible.cfg, instance.yml,"all"), more detailed see `Structure of files Ansible for vSphere`_
|
||||
|
||||
|
||||
Start
|
||||
|
||||
|
||||
Type the commands on your Terrafom instance:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder>
|
||||
terraform plan
|
||||
terraform apply
|
||||
yes
|
||||
|
||||
|
||||
After executing all the commands you will have your VyOS instance on the vSphere with your configuration, it's a very convenient desition.
|
||||
If you need to delete the instance please type the command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
terraform destroy
|
||||
|
||||
|
||||
Structure of files Terrafom for vSphere
|
||||
---------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── vyos.tf # The main script
|
||||
├── versions.tf # File for the changing version of Terraform.
|
||||
├── var.tf # File for the changing version of Terraform.
|
||||
└── terraform.tfvars # The value of all variables (passwords, login, ip adresses and so on)
|
||||
|
||||
|
||||
File contents of Terrafom for vSphere
|
||||
-------------------------------------
|
||||
|
||||
vyos.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
provider "vsphere" {
|
||||
user = var.vsphere_user
|
||||
password = var.vsphere_password
|
||||
vsphere_server = var.vsphere_server
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
|
||||
data "vsphere_datacenter" "datacenter" {
|
||||
name = var.datacenter
|
||||
}
|
||||
|
||||
data "vsphere_datastore" "datastore" {
|
||||
name = var.datastore
|
||||
datacenter_id = data.vsphere_datacenter.datacenter.id
|
||||
}
|
||||
|
||||
data "vsphere_compute_cluster" "cluster" {
|
||||
name = var.cluster
|
||||
datacenter_id = data.vsphere_datacenter.datacenter.id
|
||||
}
|
||||
|
||||
data "vsphere_resource_pool" "default" {
|
||||
name = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources/terraform") # set as you need
|
||||
datacenter_id = data.vsphere_datacenter.datacenter.id
|
||||
}
|
||||
|
||||
data "vsphere_host" "host" {
|
||||
name = var.host
|
||||
datacenter_id = data.vsphere_datacenter.datacenter.id
|
||||
}
|
||||
|
||||
data "vsphere_network" "network" {
|
||||
name = var.network_name
|
||||
datacenter_id = data.vsphere_datacenter.datacenter.id
|
||||
}
|
||||
|
||||
# Deployment of VM from Remote OVF
|
||||
resource "vsphere_virtual_machine" "vmFromRemoteOvf" {
|
||||
name = var.remotename
|
||||
datacenter_id = data.vsphere_datacenter.datacenter.id
|
||||
datastore_id = data.vsphere_datastore.datastore.id
|
||||
host_system_id = data.vsphere_host.host.id
|
||||
resource_pool_id = data.vsphere_resource_pool.default.id
|
||||
network_interface {
|
||||
network_id = data.vsphere_network.network.id
|
||||
}
|
||||
wait_for_guest_net_timeout = 2
|
||||
wait_for_guest_ip_timeout = 2
|
||||
|
||||
ovf_deploy {
|
||||
allow_unverified_ssl_cert = true
|
||||
remote_ovf_url = var.url_ova
|
||||
disk_provisioning = "thin"
|
||||
ip_protocol = "IPv4"
|
||||
ip_allocation_policy = "dhcpPolicy"
|
||||
ovf_network_map = {
|
||||
"Network 1" = data.vsphere_network.network.id
|
||||
"Network 2" = data.vsphere_network.network.id
|
||||
}
|
||||
}
|
||||
vapp {
|
||||
properties = {
|
||||
"password" = "12345678",
|
||||
"local-hostname" = "terraform_vyos"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output "ip" {
|
||||
description = "default ip address of the deployed VM"
|
||||
value = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address
|
||||
}
|
||||
|
||||
# IP of vSphere instance copied to a file ip.txt in local system
|
||||
|
||||
resource "local_file" "ip" {
|
||||
content = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address
|
||||
filename = "ip.txt"
|
||||
}
|
||||
|
||||
#Connecting to the Ansible control node using SSH connection
|
||||
|
||||
resource "null_resource" "nullremote1" {
|
||||
depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"]
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
password = var.ansiblepassword
|
||||
host = var.ansiblehost
|
||||
|
||||
}
|
||||
|
||||
# Copying the ip.txt file to the Ansible control node from local system
|
||||
|
||||
provisioner "file" {
|
||||
source = "ip.txt"
|
||||
destination = "/root/vsphere/ip.txt"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "nullremote2" {
|
||||
depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"]
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
password = var.ansiblepassword
|
||||
host = var.ansiblehost
|
||||
}
|
||||
|
||||
# Command to run ansible playbook on remote Linux OS
|
||||
|
||||
provisioner "remote-exec" {
|
||||
|
||||
inline = [
|
||||
"cd /root/vsphere/",
|
||||
"ansible-playbook instance.yml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
versions.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
terraform {
|
||||
required_providers {
|
||||
vsphere = {
|
||||
source = "hashicorp/vsphere"
|
||||
version = "2.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var.tf
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
variable "vsphere_server" {
|
||||
description = "vSphere server"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vsphere_user" {
|
||||
description = "vSphere username"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vsphere_password" {
|
||||
description = "vSphere password"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "datacenter" {
|
||||
description = "vSphere data center"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cluster" {
|
||||
description = "vSphere cluster"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "datastore" {
|
||||
description = "vSphere datastore"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "network_name" {
|
||||
description = "vSphere network name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "host" {
|
||||
description = "name if yor host"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "remotename" {
|
||||
description = "the name of you VM"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "url_ova" {
|
||||
description = "the URL to .OVA file or cloude store"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "ansiblepassword" {
|
||||
description = "Ansible password"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "ansiblehost" {
|
||||
description = "Ansible host name or IP"
|
||||
type = string
|
||||
}
|
||||
|
||||
terraform.tfvars
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vsphere_user = ""
|
||||
vsphere_password = ""
|
||||
vsphere_server = ""
|
||||
datacenter = ""
|
||||
datastore = ""
|
||||
cluster = ""
|
||||
network_name = ""
|
||||
host = ""
|
||||
url_ova = ""
|
||||
ansiblepassword = ""
|
||||
ansiblehost = ""
|
||||
remotename = ""
|
||||
|
||||
|
||||
Structure of files Ansible for vSphere
|
||||
--------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── group_vars
|
||||
└── all
|
||||
├── ansible.cfg
|
||||
└── instance.yml
|
||||
|
||||
|
||||
File contents of Ansible for vSphere
|
||||
------------------------------------
|
||||
|
||||
ansible.cfg
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[defaults]
|
||||
inventory = /root/vsphere/ip.txt
|
||||
host_key_checking= False
|
||||
remote_user=vyos
|
||||
|
||||
|
||||
instance.yml
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
##############################################################################
|
||||
# About tasks:
|
||||
# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds
|
||||
# "Configure general settings for the VyOS hosts group" - make provisioning into vSphere VyOS node
|
||||
# You have to add all necessary cammans of VyOS under the block "lines:"
|
||||
##############################################################################
|
||||
|
||||
|
||||
- name: integration of terraform and ansible
|
||||
hosts: all
|
||||
gather_facts: 'no'
|
||||
|
||||
tasks:
|
||||
|
||||
- name: "Wait 300 seconds, but only start checking after 60 seconds"
|
||||
wait_for_connection:
|
||||
delay: 60
|
||||
timeout: 300
|
||||
|
||||
- name: "Configure general settings for the VyOS hosts group"
|
||||
vyos_config:
|
||||
lines:
|
||||
- set system name-server 8.8.8.8
|
||||
save:
|
||||
true
|
||||
|
||||
|
||||
group_vars/all
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ansible_connection: ansible.netcommon.network_cli
|
||||
ansible_network_os: vyos.vyos.vyos
|
||||
|
||||
# user and password gets from terraform variables "admin_username" and "admin_password"
|
||||
ansible_user: vyos
|
||||
# get from vyos.tf "vapp"
|
||||
ansible_ssh_pass: 12345678
|
||||
|
||||
|
||||
Sourse files for vSphere from GIT
|
||||
---------------------------------
|
||||
|
||||
All files about the article can be found here_
|
||||
|
||||
.. _here: https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Vsphere_terraform_ansible_single_vyos_instance-main
|
||||
|
||||
39
docs/automation/terraform/terraformvyos.rst
Normal file
@ -0,0 +1,39 @@
|
||||
:lastproofread: 2024-03-03
|
||||
|
||||
.. _terraformvyos:
|
||||
|
||||
Terraform for VyOS
|
||||
==================
|
||||
|
||||
VyOS supports development infrastructure via Terraform and provisioning via Ansible.
|
||||
Terraform allows you to automate the process of deploying instances on many cloud and virtual platforms.
|
||||
In this article, we will look at using terraforms to deploy VyOS on platforms - AWS, Azure, and vSphere.
|
||||
For more details about Terraform please have a look here link_.
|
||||
|
||||
Need to install_ Terraform
|
||||
|
||||
Structure of files in the standard Terraform project:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
.
|
||||
├── main.tf # The main script
|
||||
├── version.tf # File for the changing version of Terraform.
|
||||
├── variables.tf # The file of all variables in "main.tf"
|
||||
└── terraform.tfvars # The value of all variables (passwords, login, ip adresses and so on)
|
||||
|
||||
|
||||
General commands that we will use for running Terraform scripts
|
||||
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
cd /<your folder> # go to the Terrafom project
|
||||
terraform init # install all addons and provider (aws az and so on)
|
||||
terraform plan # show what is changing
|
||||
terraform apply # run script
|
||||
yes # apply running
|
||||
|
||||
|
||||
.. _link: https://developer.hashicorp.com/terraform/intro
|
||||
.. _install: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
|
||||
@ -125,6 +125,38 @@ For example, get the addresses of a ``dum0`` interface.
|
||||
"error": null
|
||||
}
|
||||
|
||||
To check existence of a configuration path, use the ``exists`` operation.
|
||||
|
||||
For example, check an existing path:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
curl -k --location --request POST 'https://vyos/retrieve' \
|
||||
--form data='{"op": "exists", "path": ["service","https","api"]}' \
|
||||
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
|
||||
|
||||
response:
|
||||
{
|
||||
"success": true,
|
||||
"data": true,
|
||||
"error": null
|
||||
}
|
||||
|
||||
versus a non-existent path:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
curl -k --location --request POST 'https://vyos/retrieve' \
|
||||
--form data='{"op": "exists", "path": ["service","non","existent","path"]}' \
|
||||
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
|
||||
|
||||
response:
|
||||
{
|
||||
"success": true,
|
||||
"data": false,
|
||||
"error": null
|
||||
}
|
||||
|
||||
/reset
|
||||
======
|
||||
|
||||
@ -143,6 +175,43 @@ The ``reset`` endpoint run a ``reset`` command.
|
||||
"error": null
|
||||
}
|
||||
|
||||
/reboot
|
||||
=======
|
||||
|
||||
To initiate a reboot use the ``reboot`` endpoint.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
curl --location --request POST 'https://vyos/reboot' \
|
||||
--form data='{"op": "reboot", "path": ["now"]}' \
|
||||
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
|
||||
|
||||
respone:
|
||||
{
|
||||
"success": true,
|
||||
"data": "",
|
||||
"error": null
|
||||
}
|
||||
|
||||
/poweroff
|
||||
=========
|
||||
|
||||
To power off the system use the ``poweroff`` endpoint.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
curl --location --request POST 'https://vyos/poweroff' \
|
||||
--form data='{"op": "poweroff", "path": ["now"]}' \
|
||||
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
|
||||
|
||||
respone:
|
||||
{
|
||||
"success": true,
|
||||
"data": "",
|
||||
"error": null
|
||||
}
|
||||
|
||||
|
||||
/image
|
||||
======
|
||||
|
||||
@ -213,13 +282,14 @@ The ``generate`` endpoint run a ``generate`` command.
|
||||
.. code-block:: none
|
||||
|
||||
curl -k --location --request POST 'https://vyos/generate' \
|
||||
--form data='{"op": "generate", "path": ["wireguard", "default-keypair"]}' \
|
||||
--form data='{"op": "generate", "path": ["pki", "wireguard", "key-pair"]}' \
|
||||
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
|
||||
|
||||
response:
|
||||
{
|
||||
"success": true,
|
||||
"data": "",
|
||||
"data": "Private key: CFZR2eyhoVZwk4n3JFPMJx3E145f1EYgDM+ubytXYVY=\n
|
||||
Public key: jjtpPT8ycI1Q0bNtrWuxAkO4k88Xwzg5VHV9xGZ58lU=\n\n",
|
||||
"error": null
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ Example
|
||||
'set interfaces ethernet eth1 description LAN',
|
||||
]
|
||||
|
||||
# set congiguration
|
||||
# set configuration
|
||||
output = net_connect.send_config_set(config_commands, exit_config_mode=False)
|
||||
print(output)
|
||||
|
||||
@ -69,4 +69,4 @@ Output
|
||||
vtun10 10.10.0.1/24 u/u
|
||||
[edit]
|
||||
|
||||
.. _netmiko: https://github.com/ktbyers/netmiko
|
||||
.. _netmiko: https://github.com/ktbyers/netmiko
|
||||
|
||||
@ -8,6 +8,389 @@
|
||||
_ext/releasenotes.py
|
||||
|
||||
|
||||
2024-04-25
|
||||
==========
|
||||
|
||||
* :vytask:`T6249` ``(default): ISO builder fails because of changed buster-backport repository``
|
||||
|
||||
|
||||
2024-04-23
|
||||
==========
|
||||
|
||||
* :vytask:`T6261` ``(default): Typo in op_mode connect_disconnect print statement for check_ppp_running``
|
||||
|
||||
|
||||
2024-04-17
|
||||
==========
|
||||
|
||||
* :vytask:`T6243` ``(bug): Update vyos-http-api-tools for package idna security advisory``
|
||||
|
||||
|
||||
2024-04-12
|
||||
==========
|
||||
|
||||
* :vytask:`T3437` ``(bug): BGP Confederation Addition Causes Error``
|
||||
|
||||
|
||||
2024-04-10
|
||||
==========
|
||||
|
||||
* :vytask:`T6124` ``(bug): Docker equuleus build image doesn't build due to fpm``
|
||||
|
||||
|
||||
2024-04-08
|
||||
==========
|
||||
|
||||
* :vytask:`T6196` ``(bug): Route-map and summary-only do not work in BGP aggregation at the same time``
|
||||
|
||||
|
||||
2024-04-07
|
||||
==========
|
||||
|
||||
* :vytask:`T1244` ``(default): Support for StartupResync in conntrackd``
|
||||
|
||||
|
||||
2024-04-05
|
||||
==========
|
||||
|
||||
* :vytask:`T2590` ``(bug): DHCPv6 not updating nameservers and search domains since replacing isc-dhcp-client with WIDE dhcp6c``
|
||||
|
||||
|
||||
2024-04-04
|
||||
==========
|
||||
|
||||
* :vytask:`T4146` ``(bug): Nginx should not listen on port 80``
|
||||
* :vytask:`T1976` ``(default): deleting address-family under neighbor will disable neighbor``
|
||||
* :vytask:`T5625` ``(default): "restart vpn" does not work if ipsec-interfaces is not set``
|
||||
* :vytask:`T3020` ``(bug): The "scp" example is wrong in the bash-completion for "set system config-management commit-archive location"``
|
||||
* :vytask:`T2250` ``(default): vyos-build "make iso" error if configure was ran outside of the docker container``
|
||||
* :vytask:`T2139` ``(default): openvpn: allow "dh-file none" to disable DH for ECDH keys``
|
||||
* :vytask:`T2014` ``(default): Use vendor specific NTP Pool hostname``
|
||||
* :vytask:`T1118` ``(bug): Obsolete "utc" option in time selector in firewall``
|
||||
* :vytask:`T948` ``(feature): integrate aws cloud watch scripts into AMI``
|
||||
|
||||
|
||||
2024-04-02
|
||||
==========
|
||||
|
||||
* :vytask:`T6150` ``(bug): Impossible to set a static IP address via Radius in IPoE``
|
||||
|
||||
|
||||
2024-04-01
|
||||
==========
|
||||
|
||||
* :vytask:`T6193` ``(bug): dhcp-client: invalid warning "is not a DHCP interface but uses DHCP name-server option" for VLAN interfaces``
|
||||
|
||||
|
||||
2024-03-22
|
||||
==========
|
||||
|
||||
* :vytask:`T6110` ``(bug): dhcp server - If failover is defined, range is required``
|
||||
* :vytask:`T5624` ``(default): Remove /etc/debian_version from the image``
|
||||
|
||||
|
||||
2024-03-11
|
||||
==========
|
||||
|
||||
* :vytask:`T2998` ``(bug): SNMP v3 oid "exclude" option doesn't work``
|
||||
* :vytask:`T6096` ``(bug): Config commits are not synced properly because 00vyos-sync is deleted by vyos-router``
|
||||
* :vytask:`T6057` ``(feature): Add ability to disable syslog for conntrackd``
|
||||
* :vytask:`T5504` ``(feature): Keepalived VRRP ability to set more than one peer-address``
|
||||
|
||||
|
||||
2024-03-07
|
||||
==========
|
||||
|
||||
* :vytask:`T3992` ``(bug): Traceback on adding interface to bridge with configured ip address``
|
||||
|
||||
|
||||
2024-03-06
|
||||
==========
|
||||
|
||||
* :vytask:`T6088` ``(bug): Configuration corrupted after saving and powercut or force reboot``
|
||||
|
||||
|
||||
2024-02-16
|
||||
==========
|
||||
|
||||
* :vytask:`T2113` ``(bug): OpenVPN Options error: you cannot use --verify-x509-name with --compat-names or --no-name-remapping``
|
||||
* :vytask:`T5418` ``(bug): PPPoE-Server Client IP pool Subnet``
|
||||
|
||||
|
||||
2024-02-15
|
||||
==========
|
||||
|
||||
* :vytask:`T2612` ``(bug): HTTPS API, changing API key fails but goes through``
|
||||
* :vytask:`T656` ``(enhancment): Rewrite wirelessmodem in new style XML interface definition``
|
||||
|
||||
|
||||
2024-02-14
|
||||
==========
|
||||
|
||||
* :vytask:`T2044` ``(bug): RPKI doesn't boot properly``
|
||||
|
||||
|
||||
2024-02-08
|
||||
==========
|
||||
|
||||
* :vytask:`T6014` ``(feature): Bump keepalived version``
|
||||
|
||||
|
||||
2024-02-07
|
||||
==========
|
||||
|
||||
* :vytask:`T6017` ``(bug): Update vyos-http-api-tools for security advisory``
|
||||
|
||||
|
||||
2024-02-02
|
||||
==========
|
||||
|
||||
* :vytask:`T5914` ``(bug): CVE-2023-48795 - Terrapin vulnerability``
|
||||
* :vytask:`T5739` ``(bug): Password recovery does not work if public keys are configured``
|
||||
|
||||
|
||||
2024-02-01
|
||||
==========
|
||||
|
||||
* :vytask:`T5967` ``(bug): Multi-hop BFD connections can't be established; please add minimum-ttl option.``
|
||||
|
||||
|
||||
2024-01-22
|
||||
==========
|
||||
|
||||
* :vytask:`T4721` ``(feature): Static IPv6 Route Tags Missing``
|
||||
|
||||
|
||||
2024-01-20
|
||||
==========
|
||||
|
||||
* :vytask:`T5187` ``(bug): Update Realtek r8152 driver``
|
||||
* :vytask:`T5182` ``(bug): Update Intel ice driver``
|
||||
* :vytask:`T5180` ``(bug): initramfs-tools ignores firmware from updates directory``
|
||||
* :vytask:`T4990` ``(bug): Commit results may not be properly saved if power is cut immediately after a successful commit``
|
||||
* :vytask:`T4039` ``(feature): Rsyslog to use 'protocol23format' for protocol UDP``
|
||||
* :vytask:`T3813` ``(bug): Some custom sysctl parameters can't be applied bug``
|
||||
* :vytask:`T2579` ``(feature): The root task for VRF features``
|
||||
* :vytask:`T2546` ``(feature): The root task for rewriting [op-mode] to XML``
|
||||
* :vytask:`T2452` ``(default): Serial console related issues``
|
||||
|
||||
|
||||
2024-01-19
|
||||
==========
|
||||
|
||||
* :vytask:`T5543` ``(bug): Fix source address handling in static joins``
|
||||
|
||||
|
||||
2024-01-14
|
||||
==========
|
||||
|
||||
* :vytask:`T5715` ``(bug): IPSec VPN: restart vpn is not working``
|
||||
|
||||
|
||||
2024-01-13
|
||||
==========
|
||||
|
||||
* :vytask:`T5924` ``(bug): Build cannot pass the smoketest dialup-router-medium-vpn``
|
||||
|
||||
|
||||
2024-01-11
|
||||
==========
|
||||
|
||||
* :vytask:`T5275` ``(default): Add op mode commands for exporting certificates to PEM files with correct headers``
|
||||
* :vytask:`T5274` ``(default): Add a deprecation warning for OpenVPN site-to-site with pre-shared secret``
|
||||
* :vytask:`T3191` ``(bug): PAM RADIUS freezing when accounting does not configured on RADIUS server``
|
||||
|
||||
|
||||
2024-01-10
|
||||
==========
|
||||
|
||||
* :vytask:`T4646` ``(bug): USB serial output console does not work``
|
||||
* :vytask:`T4466` ``(bug): intel i225-v nic does not detect link after boot``
|
||||
* :vytask:`T4222` ``(feature): Support for TWAMP as round-trip metric``
|
||||
* :vytask:`T1369` ``(bug): GCP Networking Failure``
|
||||
|
||||
|
||||
2024-01-09
|
||||
==========
|
||||
|
||||
* :vytask:`T3242` ``(bug): PPPoE Server overhead on virtual interfaces creation``
|
||||
* :vytask:`T2755` ``(default): Requirements for partial interface setup``
|
||||
* :vytask:`T2494` ``(bug): systemd dependencies issues``
|
||||
* :vytask:`T2343` ``(feature): Disable memory ballooning in VM templates``
|
||||
* :vytask:`T2254` ``(default): Provide more information on the build branch in the version data``
|
||||
* :vytask:`T2223` ``(feature): convert operational show interfaces to python/XML``
|
||||
* :vytask:`T1925` ``(bug): DMVPN is always listed as down in "show vpn ipsec sa"``
|
||||
* :vytask:`T1297` ``(feature): Add GARP settings to VRRP/keepalived``
|
||||
|
||||
|
||||
2024-01-08
|
||||
==========
|
||||
|
||||
* :vytask:`T5318` ``(bug): Security Vulnerabilities for VyOS 1.3.3``
|
||||
* :vytask:`T3980` ``(bug): vrrp transition-script validator makes warning fatal and also causes a python NameError exception``
|
||||
* :vytask:`T2799` ``(feature): VyOS Certificates Manager``
|
||||
|
||||
|
||||
2023-12-29
|
||||
==========
|
||||
|
||||
* :vytask:`T5852` ``(bug): Reboots fail with eapol WAN interface``
|
||||
|
||||
|
||||
2023-12-22
|
||||
==========
|
||||
|
||||
* :vytask:`T4760` ``(bug): VyOS does not support running multiple instances of DHCPv6 clients``
|
||||
|
||||
|
||||
2023-12-21
|
||||
==========
|
||||
|
||||
* :vytask:`T5714` ``(bug): IPSec VPN: op-mode: "show log vpn" does not show results``
|
||||
* :vytask:`T3039` ``(feature): Resize a root partition and filesystem automatically during deployment in virtual environments``
|
||||
* :vytask:`T2404` ``(bug): Cannot change MTU``
|
||||
* :vytask:`T2353` ``(bug): Interface [conf_mode] errors parent task``
|
||||
* :vytask:`T5796` ``(bug): Openconnect - HTTPS security headers are missing``
|
||||
|
||||
|
||||
2023-12-19
|
||||
==========
|
||||
|
||||
* :vytask:`T2116` ``(feature): Processing configuration via Cloud-init User-Data``
|
||||
|
||||
|
||||
2023-12-18
|
||||
==========
|
||||
|
||||
* :vytask:`T2191` ``(feature): Using tallow to block sshd probes``
|
||||
|
||||
|
||||
2023-12-15
|
||||
==========
|
||||
|
||||
* :vytask:`T5824` ``(bug): busybox cannot connect some websites from initramfs``
|
||||
|
||||
|
||||
2023-12-12
|
||||
==========
|
||||
|
||||
* :vytask:`T5817` ``(bug): Show openvpn server fails in some cases``
|
||||
* :vytask:`T5413` ``(default): Deny the opportunity to use one public/private key pair on both wireguard peers.``
|
||||
|
||||
|
||||
2023-11-30
|
||||
==========
|
||||
|
||||
* :vytask:`T4601` ``(bug): dhcp : relay agent IP address issue.``
|
||||
|
||||
|
||||
2023-11-28
|
||||
==========
|
||||
|
||||
* :vytask:`T5777` ``(bug): frr: backport and upstream recent bgpd daemon crashes``
|
||||
|
||||
|
||||
2023-11-27
|
||||
==========
|
||||
|
||||
* :vytask:`T5763` ``(bug): Fix imprecise check for remote file name in vyos-load-config.py``
|
||||
|
||||
|
||||
2023-11-25
|
||||
==========
|
||||
|
||||
* :vytask:`T5655` ``(bug): commit-archive: Ctrl+C should not eror out with stack trace, signal should be cought``
|
||||
|
||||
|
||||
2023-11-24
|
||||
==========
|
||||
|
||||
* :vytask:`T5402` ``(bug): VRRP router with rfc3768-compatibility sends multiple ARP replies``
|
||||
|
||||
|
||||
2023-11-22
|
||||
==========
|
||||
|
||||
* :vytask:`T5578` ``(bug): "ikev2-reauth" description contains outdated information``
|
||||
|
||||
|
||||
2023-11-15
|
||||
==========
|
||||
|
||||
* :vytask:`T5661` ``(enhancment): Add show show ssh dynamic-protection attacker and show log ssh dynamic-protection``
|
||||
* :vytask:`T1276` ``(bug): dhcp relay + VLAN fails``
|
||||
|
||||
|
||||
2023-11-07
|
||||
==========
|
||||
|
||||
* :vytask:`T5586` ``(feature): Disable by default SNMP for Keepalived VRRP``
|
||||
|
||||
|
||||
2023-11-06
|
||||
==========
|
||||
|
||||
* :vytask:`T4269` ``(feature): node.def generator should automatically add default values``
|
||||
|
||||
|
||||
2023-10-26
|
||||
==========
|
||||
|
||||
* :vytask:`T5684` ``(bug): services using VRF generates the error "Failed to load BPF prog: 'Operation not permitted'" when the system boots.``
|
||||
* :vytask:`T5594` ``(bug): VRRP - Error if using IPv6 Link Local as hello source address``
|
||||
|
||||
|
||||
2023-10-21
|
||||
==========
|
||||
|
||||
* :vytask:`T5670` ``(bug): bridge: missing member interface validator``
|
||||
* :vytask:`T5191` ``(default): Replace underscores with hyphens in command-line options generated by vyos.opmode``
|
||||
* :vytask:`T4402` ``(bug): OpenVPN client-ip-pool option is broken``
|
||||
* :vytask:`T2719` ``(feature): Standardized op mode script structure``
|
||||
|
||||
|
||||
2023-10-19
|
||||
==========
|
||||
|
||||
* :vytask:`T5669` ``(bug): VXLAN interface changing port does not work``
|
||||
|
||||
|
||||
2023-10-17
|
||||
==========
|
||||
|
||||
* :vytask:`T5235` ``(bug): SSH keys with special characters cannot be applied via Cloud-init``
|
||||
|
||||
|
||||
2023-10-08
|
||||
==========
|
||||
|
||||
* :vytask:`T5630` ``(feature): pppoe: allow to specify MRU in addition to already configurable MTU``
|
||||
|
||||
|
||||
2023-10-06
|
||||
==========
|
||||
|
||||
* :vytask:`T5576` ``(feature): Add bgp remove-private-as all option``
|
||||
|
||||
|
||||
2023-10-04
|
||||
==========
|
||||
|
||||
* :vytask:`T5632` ``(feature): Add jq package to parse JSON files``
|
||||
|
||||
|
||||
2023-09-25
|
||||
==========
|
||||
|
||||
* :vytask:`T5533` ``(bug): Keepalived VRRP IPv6 group enters in FAULT state``
|
||||
|
||||
|
||||
2023-09-20
|
||||
==========
|
||||
|
||||
* :vytask:`T5271` ``(default): Add support for peer-fingerprint to OpenVPN``
|
||||
|
||||
|
||||
2023-09-11
|
||||
==========
|
||||
|
||||
@ -51,7 +434,7 @@
|
||||
* :vytask:`T4874` ``(default): Add Warning message to Equuleus``
|
||||
* :vytask:`T4855` ``(bug): Trying to create more than one tunnel of the same type to the same address causes unhandled exception``
|
||||
* :vytask:`T4776` ``(bug): NVME storage is not detected properly during installation``
|
||||
* :vytask:`T3546` ``(feature): Add pppoe-server CLI custom script feature``
|
||||
* :vytask:`T3546` ``(feature): Add support for running scripts on PPPoE server session events``
|
||||
* :vytask:`T738` ``(feature): Add local-port and resolver port options for powerdns in CLI configuration tree``
|
||||
|
||||
|
||||
@ -77,7 +460,6 @@
|
||||
* :vytask:`T3940` ``(bug): DHCP client does not remove IP address when stopped by the 02-vyos-stopdhclient hook``
|
||||
* :vytask:`T3713` ``(default): Create a meta-package for user utilities``
|
||||
* :vytask:`T3339` ``(bug): Cloud-Init domain search setting not applied``
|
||||
* :vytask:`T3144` ``(feature): Support op-mode command to release DHCP leases``
|
||||
* :vytask:`T2640` ``(feature): Running VyOS inside Docker containers``
|
||||
* :vytask:`T3577` ``(bug): Generating vpn x509 key pair fails with command not found``
|
||||
|
||||
@ -200,12 +582,6 @@
|
||||
* :vytask:`T5313` ``(bug): UDP broadcast relay - missing verify() that relay interfaces have an IP address assigned``
|
||||
|
||||
|
||||
2023-06-28
|
||||
==========
|
||||
|
||||
* :vytask:`T1237` ``(feature): Static Route Path Monitoring, failover``
|
||||
|
||||
|
||||
2023-06-26
|
||||
==========
|
||||
|
||||
@ -225,6 +601,12 @@
|
||||
* :vytask:`T5280` ``(bug): Update Expired keys (2023-06-08) for PowerDNS``
|
||||
|
||||
|
||||
2023-06-13
|
||||
==========
|
||||
|
||||
* :vytask:`T5213` ``(feature): Accel-ppp sending accounting interim updates acct-interim-interval option``
|
||||
|
||||
|
||||
2023-05-29
|
||||
==========
|
||||
|
||||
@ -1830,7 +2212,6 @@
|
||||
==========
|
||||
|
||||
* :vytask:`T3682` ``(bug): Remove running dhclient from ether-resume.py``
|
||||
* :vytask:`T3681` ``(default): The VMware Tools resume script did not run successfully in this virtual machine.``
|
||||
|
||||
|
||||
2021-08-20
|
||||
|
||||
50
docs/cli.rst
@ -369,7 +369,7 @@ command.
|
||||
|
||||
You are now in a sublevel relative to ``interfaces ethernet eth0``, all
|
||||
commands executed from this point on are relative to this sublevel. Use
|
||||
eithe the :cfgcmd:`top` or :cfgcmd:`exit` command to go back to the top
|
||||
either the :cfgcmd:`top` or :cfgcmd:`exit` command to go back to the top
|
||||
of the hierarchy. You can also use the :cfgcmd:`up` command to move only
|
||||
one level up at a time.
|
||||
|
||||
@ -410,7 +410,7 @@ working configuration indicating line changes with ``+`` for additions,
|
||||
loopback lo {
|
||||
}
|
||||
|
||||
It is also possible to display all `set` commands within configuration
|
||||
It is also possible to display all :cfgcmd:`set` commands within configuration
|
||||
mode using :cfgcmd:`show | commands`
|
||||
|
||||
.. code-block:: none
|
||||
@ -501,6 +501,9 @@ different levels in the hierarchy.
|
||||
Warning: configuration changes have not been saved.
|
||||
vyos@vyos:~$
|
||||
|
||||
.. hint:: You can specify a commit message with
|
||||
:cfgcmd:`commit comment <message>`.
|
||||
|
||||
.. _save:
|
||||
|
||||
.. cfgcmd:: save
|
||||
@ -558,7 +561,7 @@ different levels in the hierarchy.
|
||||
What if you are doing something dangerous? Suppose you want to setup
|
||||
a firewall, and you are not sure there are no mistakes that will lock
|
||||
you out of your system. You can use confirmed commit. If you issue
|
||||
the ``commit-confirm`` command, your changes will be commited, and if
|
||||
the ``commit-confirm`` command, your changes will be committed, and if
|
||||
you don't issue the ``confirm`` command in 10 minutes, your
|
||||
system will reboot into previous config revision.
|
||||
|
||||
@ -653,7 +656,7 @@ different levels in the hierarchy.
|
||||
The ``comment`` command allows you to insert a comment above the
|
||||
``<config node>`` configuration section. When shown, comments are
|
||||
enclosed with ``/*`` and ``*/`` as open/close delimiters. Comments
|
||||
need to be commited, just like other config changes.
|
||||
need to be committed, just like other config changes.
|
||||
|
||||
To remove an existing comment from your current configuration,
|
||||
specify an empty string enclosed in double quote marks (``""``) as
|
||||
@ -852,30 +855,39 @@ Remote Archive
|
||||
VyOS can upload the configuration to a remote location after each call
|
||||
to :cfgcmd:`commit`. You will have to set the commit-archive location.
|
||||
TFTP, FTP, SCP and SFTP servers are supported. Every time a
|
||||
:cfgcmd:`commit` is successfull the ``config.boot`` file will be copied
|
||||
:cfgcmd:`commit` is successful the ``config.boot`` file will be copied
|
||||
to the defined destination(s). The filename used on the remote host will
|
||||
be ``config.boot-hostname.YYYYMMDD_HHMMSS``.
|
||||
be ``config.boot-hostname.YYYYMMDD_HHMMSS``.
|
||||
|
||||
.. cfgcmd:: set system config-management commit-archive location <URI>
|
||||
|
||||
Specify remote location of commit archive as any of the below
|
||||
:abbr:`URI (Uniform Resource Identifier)`
|
||||
Specify remote location of commit archive as any of the below
|
||||
:abbr:`URI (Uniform Resource Identifier)`
|
||||
|
||||
* ``scp://<user>:<passwd>@<host>:/<dir>``
|
||||
* ``sftp://<user>:<passwd>@<host>/<dir>``
|
||||
* ``ftp://<user>:<passwd>@<host>/<dir>``
|
||||
* ``tftp://<host>/<dir>``
|
||||
* ``http://<user>:<passwd>@<host>:/<dir>``
|
||||
* ``https://<user>:<passwd>@<host>:/<dir>``
|
||||
* ``ftp://<user>:<passwd>@<host>/<dir>``
|
||||
* ``sftp://<user>:<passwd>@<host>/<dir>``
|
||||
* ``scp://<user>:<passwd>@<host>:/<dir>``
|
||||
* ``tftp://<host>/<dir>``
|
||||
* ``git+https://<user>:<passwd>@<host>/<path>``
|
||||
|
||||
.. note:: The number of revisions don't affect the commit-archive.
|
||||
Since username and password are part of the URI, they need to be
|
||||
properly url encoded if containing special characters.
|
||||
|
||||
.. note:: You may find VyOS not allowing the secure connection because
|
||||
it cannot verify the legitimacy of the remote server. You can use
|
||||
the workaround below to quickly add the remote host's SSH
|
||||
fingerprint to your ``~/.ssh/known_hosts`` file:
|
||||
.. note:: The number of revisions don't affect the commit-archive.
|
||||
|
||||
.. code-block:: none
|
||||
.. note:: When using Git as destination for the commit archive the
|
||||
``source-address`` CLI option has no effect.
|
||||
|
||||
vyos@vyos# ssh-keyscan <host> >> ~/.ssh/known_hosts
|
||||
.. note:: You may find VyOS not allowing the secure connection because
|
||||
it cannot verify the legitimacy of the remote server. You can use
|
||||
the workaround below to quickly add the remote host's SSH
|
||||
fingerprint to your ``~/.ssh/known_hosts`` file:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos# ssh-keyscan <host> >> ~/.ssh/known_hosts
|
||||
|
||||
Saving and loading manually
|
||||
---------------------------
|
||||
|
||||
@ -22,7 +22,7 @@ from docutils.parsers.rst.roles import set_classes
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = u'VyOS'
|
||||
copyright = u'2021, VyOS maintainers and contributors'
|
||||
copyright = u'2023, VyOS maintainers and contributors'
|
||||
author = u'VyOS maintainers and contributors'
|
||||
|
||||
# The short X.Y version
|
||||
@ -47,7 +47,7 @@ extensions = ['sphinx.ext.intersphinx',
|
||||
'notfound.extension',
|
||||
'autosectionlabel',
|
||||
'myst_parser',
|
||||
'sphinx_panels',
|
||||
'sphinx_design',
|
||||
'vyos'
|
||||
]
|
||||
|
||||
|
||||
@ -7,9 +7,9 @@ OpenVPN with LDAP
|
||||
| Testdate: 2023-05-11
|
||||
| Version: 1.4-rolling-202305100734
|
||||
|
||||
This LAB show how to uwe OpenVPN with a Active Directory authentication backend.
|
||||
This LAB shows how to use OpenVPN with a Active Directory authentication method.
|
||||
|
||||
The Topology are consists of:
|
||||
Topology consists of:
|
||||
* Windows Server 2019 with a running Active Directory
|
||||
* VyOS as a OpenVPN Server
|
||||
* VyOS as Client
|
||||
@ -20,7 +20,7 @@ The Topology are consists of:
|
||||
Active Directory on Windows server
|
||||
==================================
|
||||
|
||||
The Lab asume a full running Active Directory on the Windows Server.
|
||||
The lab assumes a full running Active Directory on the Windows Server.
|
||||
Here are some PowerShell commands to quickly add a Test Active Directory.
|
||||
|
||||
.. code-block:: powershell
|
||||
@ -36,7 +36,7 @@ Here are some PowerShell commands to quickly add a Test Active Directory.
|
||||
New-ADUser user01 -AccountPassword(Read-Host -AsSecureString "Input Password") -Enabled $true
|
||||
|
||||
|
||||
Configuration VyOS as OpenVPN Server
|
||||
Configure VyOS as OpenVPN Server
|
||||
====================================
|
||||
|
||||
In this example OpenVPN will be setup with a client certificate and username / password authentication.
|
||||
@ -53,7 +53,7 @@ Please look :ref:`here <configuration/pki/index:pki>` for more information.
|
||||
|
||||
Now generate all required certificates on the ovpn-server:
|
||||
|
||||
first the PCA
|
||||
First the CA
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
@ -249,11 +249,27 @@ save the output to a file and import it in nearly all openvpn clients.
|
||||
|
||||
</key>
|
||||
|
||||
Configure VyOS as client
|
||||
------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set interfaces openvpn vtun10 authentication username 'user01'
|
||||
set interfaces openvpn vtun10 authentication password '$ecret'
|
||||
set interfaces openvpn vtun10 encryption cipher 'aes256'
|
||||
set interfaces openvpn vtun10 hash 'sha512'
|
||||
set interfaces openvpn vtun10 mode 'client'
|
||||
set interfaces openvpn vtun10 persistent-tunnel
|
||||
set interfaces openvpn vtun10 protocol 'udp'
|
||||
set interfaces openvpn vtun10 remote-host '198.51.100.254'
|
||||
set interfaces openvpn vtun10 remote-port '1194'
|
||||
set interfaces openvpn vtun10 tls ca-certificate 'OVPN-CA'
|
||||
set interfaces openvpn vtun10 tls certificate 'CLIENT'
|
||||
|
||||
Monitoring
|
||||
==========
|
||||
|
||||
If the client is connect successfully you can check the output with
|
||||
If the client is connected successfully you can check the status
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ This chapter contains various configuration examples:
|
||||
wan-load-balancing
|
||||
pppoe-ipv6-basic
|
||||
l3vpn-hub-and-spoke
|
||||
lac-lns
|
||||
inter-vrf-routing-vrf-lite
|
||||
qos
|
||||
segment-routing-isis
|
||||
|
||||
169
docs/configexamples/lac-lns.rst
Normal file
@ -0,0 +1,169 @@
|
||||
:lastproofread: 2024-02-21
|
||||
|
||||
.. _examples-lac-lns:
|
||||
|
||||
###############
|
||||
PPPoE over L2TP
|
||||
###############
|
||||
|
||||
This document is to describe a basic setup using PPPoE over L2TP.
|
||||
LAC and LNS are components of the broadband topology.
|
||||
LAC - L2TP access concentrator
|
||||
LNS - L2TP Network Server
|
||||
LAC and LNS forms L2TP tunnel. LAC receives packets from PPPoE clients and
|
||||
forward them to LNS. LNS is the termination point that comes from PPP packets
|
||||
from the remote client.
|
||||
|
||||
In this example we use VyOS 1.5 as LNS and Cisco IOS as LAC.
|
||||
All users with domain **vyos.io** will be tunneled to LNS via L2TP.
|
||||
|
||||
Network Topology
|
||||
================
|
||||
|
||||
.. image:: /_static/images/lac-lns-diagram.jpg
|
||||
:width: 60%
|
||||
:align: center
|
||||
:alt: Network Topology Diagram
|
||||
|
||||
Configurations
|
||||
==============
|
||||
|
||||
LAC
|
||||
---
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
aaa new-model
|
||||
!
|
||||
aaa authentication ppp default local
|
||||
!
|
||||
vpdn enable
|
||||
vpdn aaa attribute nas-ip-address vpdn-nas
|
||||
!
|
||||
vpdn-group LAC
|
||||
request-dialin
|
||||
protocol l2tp
|
||||
domain vyos.io
|
||||
initiate-to ip 192.168.139.100
|
||||
source-ip 192.168.139.101
|
||||
local name LAC
|
||||
l2tp tunnel password 0 test123
|
||||
!
|
||||
bba-group pppoe MAIN-BBA
|
||||
virtual-template 1
|
||||
!
|
||||
interface GigabitEthernet0/0
|
||||
description To LNS
|
||||
ip address 192.168.139.101 255.255.255.0
|
||||
duplex auto
|
||||
speed auto
|
||||
media-type rj45
|
||||
!
|
||||
interface GigabitEthernet0/1
|
||||
description To PPPoE clients
|
||||
no ip address
|
||||
duplex auto
|
||||
speed auto
|
||||
media-type rj45
|
||||
pppoe enable group MAIN-BBA
|
||||
!
|
||||
|
||||
LNS
|
||||
---
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set interfaces ethernet eth0 address '192.168.139.100/24'
|
||||
set nat source rule 100 outbound-interface name 'eth0'
|
||||
set nat source rule 100 source address '10.0.0.0/24'
|
||||
set nat source rule 100 translation address 'masquerade'
|
||||
set protocols static route 0.0.0.0/0 next-hop 192.168.139.2
|
||||
set vpn l2tp remote-access authentication mode 'radius'
|
||||
set vpn l2tp remote-access authentication radius server 192.168.139.110 key 'radiustest'
|
||||
set vpn l2tp remote-access client-ip-pool TEST-POOL range '10.0.0.2-10.0.0.100'
|
||||
set vpn l2tp remote-access default-pool 'TEST-POOL'
|
||||
set vpn l2tp remote-access gateway-address '10.0.0.1'
|
||||
set vpn l2tp remote-access lns host-name 'LAC'
|
||||
set vpn l2tp remote-access lns shared-secret 'test123'
|
||||
set vpn l2tp remote-access name-server '8.8.8.8'
|
||||
set vpn l2tp remote-access ppp-options disable-ccp
|
||||
|
||||
.. note:: This setup requires the Compression Control Protocol (CCP)
|
||||
being disabled, the command ``set vpn l2tp remote-access ppp-options disable-ccp``
|
||||
accomplishes that.
|
||||
|
||||
Client
|
||||
------
|
||||
|
||||
In this lab we use Windows PPPoE client.
|
||||
|
||||
.. image:: /_static/images/lac-lns-winclient.jpg
|
||||
:width: 100%
|
||||
:align: center
|
||||
:alt: Window PPPoE Client Configuration
|
||||
|
||||
Monitoring
|
||||
----------
|
||||
|
||||
Monitoring on LNS side
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos:~$ show l2tp-server sessions
|
||||
ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes
|
||||
--------+--------------+----------+-----+--------+-----------------+------------+--------+----------+-----------+----------
|
||||
l2tp0 | test@vyos.io | 10.0.0.2 | | | 192.168.139.101 | | active | 00:00:35 | 188.4 KiB | 9.3 MiB
|
||||
|
||||
Monitoring on LAC side
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Router#show pppoe session
|
||||
1 session in FORWARDED (FWDED) State
|
||||
1 session total
|
||||
Uniq ID PPPoE RemMAC Port VT VA State
|
||||
SID LocMAC VA-st Type
|
||||
1 1 000c.290b.20a6 Gi0/1 1 N/A FWDED
|
||||
0c58.88ac.0001
|
||||
|
||||
Router#show l2tp
|
||||
L2TP Tunnel and Session Information Total tunnels 1 sessions 1
|
||||
|
||||
LocTunID RemTunID Remote Name State Remote Address Sessn L2TP Class/
|
||||
Count VPDN Group
|
||||
23238 2640 LAC est 192.168.139.100 1 LAC
|
||||
|
||||
LocID RemID TunID Username, Intf/ State Last Chg Uniq ID
|
||||
Vcid, Circuit
|
||||
25641 25822 23238 test@vyos.io, Gi0/1 est 00:05:36 1
|
||||
|
||||
Monitoring on RADIUS Server side
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
root@Radius:~# cat /var/log/freeradius/radacct/192.168.139.100/detail-20240221
|
||||
Wed Feb 21 13:37:17 2024
|
||||
User-Name = "test@vyos.io"
|
||||
NAS-Port = 0
|
||||
NAS-Port-Id = "l2tp0"
|
||||
NAS-Port-Type = Virtual
|
||||
Service-Type = Framed-User
|
||||
Framed-Protocol = PPP
|
||||
Calling-Station-Id = "192.168.139.101"
|
||||
Called-Station-Id = "192.168.139.100"
|
||||
Acct-Status-Type = Start
|
||||
Acct-Authentic = RADIUS
|
||||
Acct-Session-Id = "45c731e169d9a4f1"
|
||||
Acct-Session-Time = 0
|
||||
Acct-Input-Octets = 0
|
||||
Acct-Output-Octets = 0
|
||||
Acct-Input-Packets = 0
|
||||
Acct-Output-Packets = 0
|
||||
Acct-Input-Gigawords = 0
|
||||
Acct-Output-Gigawords = 0
|
||||
Framed-IP-Address = 10.0.0.2
|
||||
NAS-IP-Address = 192.168.139.100
|
||||
Event-Timestamp = "Feb 21 2024 13:37:17 UTC"
|
||||
Tmp-String-9 = "ai:"
|
||||
Acct-Unique-Session-Id = "ea6a1089816f19c0d0f1819bc61c3318"
|
||||
Timestamp = 1708522637
|
||||
@ -89,24 +89,28 @@ To have basic protection while keeping IPv6 network functional, we need to:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall ipv6-name WAN_IN default-action 'drop'
|
||||
set firewall ipv6-name WAN_IN rule 10 action 'accept'
|
||||
set firewall ipv6-name WAN_IN rule 10 state established 'enable'
|
||||
set firewall ipv6-name WAN_IN rule 10 state related 'enable'
|
||||
set firewall ipv6-name WAN_IN rule 20 action 'accept'
|
||||
set firewall ipv6-name WAN_IN rule 20 protocol 'icmpv6'
|
||||
set firewall ipv6-name WAN_LOCAL default-action 'drop'
|
||||
set firewall ipv6-name WAN_LOCAL rule 10 action 'accept'
|
||||
set firewall ipv6-name WAN_LOCAL rule 10 state established 'enable'
|
||||
set firewall ipv6-name WAN_LOCAL rule 10 state related 'enable'
|
||||
set firewall ipv6-name WAN_LOCAL rule 20 action 'accept'
|
||||
set firewall ipv6-name WAN_LOCAL rule 20 protocol 'icmpv6'
|
||||
set firewall ipv6-name WAN_LOCAL rule 30 action 'accept'
|
||||
set firewall ipv6-name WAN_LOCAL rule 30 destination port '546'
|
||||
set firewall ipv6-name WAN_LOCAL rule 30 protocol 'udp'
|
||||
set firewall ipv6-name WAN_LOCAL rule 30 source port '547'
|
||||
set interfaces pppoe pppoe0 firewall in ipv6-name 'WAN_IN'
|
||||
set interfaces pppoe pppoe0 firewall local ipv6-name 'WAN_LOCAL'
|
||||
set firewall ipv6 name WAN_IN default-action 'drop'
|
||||
set firewall ipv6 name WAN_IN rule 10 action 'accept'
|
||||
set firewall ipv6 name WAN_IN rule 10 state established 'enable'
|
||||
set firewall ipv6 name WAN_IN rule 10 state related 'enable'
|
||||
set firewall ipv6 name WAN_IN rule 20 action 'accept'
|
||||
set firewall ipv6 name WAN_IN rule 20 protocol 'icmpv6'
|
||||
set firewall ipv6 name WAN_LOCAL default-action 'drop'
|
||||
set firewall ipv6 name WAN_LOCAL rule 10 action 'accept'
|
||||
set firewall ipv6 name WAN_LOCAL rule 10 state established 'enable'
|
||||
set firewall ipv6 name WAN_LOCAL rule 10 state related 'enable'
|
||||
set firewall ipv6 name WAN_LOCAL rule 20 action 'accept'
|
||||
set firewall ipv6 name WAN_LOCAL rule 20 protocol 'icmpv6'
|
||||
set firewall ipv6 name WAN_LOCAL rule 30 action 'accept'
|
||||
set firewall ipv6 name WAN_LOCAL rule 30 destination port '546'
|
||||
set firewall ipv6 name WAN_LOCAL rule 30 protocol 'udp'
|
||||
set firewall ipv6 name WAN_LOCAL rule 30 source port '547'
|
||||
set firewall ipv6 forward filter rule 10 action jump
|
||||
set firewall ipv6 forward filter rule 10 jump-target 'WAN_IN'
|
||||
set firewall ipv6 forward filter rule 10 inbound-interface name 'pppoe0'
|
||||
set firewall ipv6 input filter rule 10 action jump
|
||||
set firewall ipv6 input filter rule 10 jump-target 'WAN_LOCAL'
|
||||
set firewall ipv6 input filter rule 10 inbound-interface name 'pppoe0'
|
||||
|
||||
Note to allow the router to receive DHCPv6 response from ISP. We need to allow
|
||||
packets with source port 547 (server) and destination port 546 (client).
|
||||
|
||||
@ -11,7 +11,7 @@ Zone-Policy example
|
||||
found in the `firewall
|
||||
<https://docs.vyos.io/en/latest/configuration/firewall/general.html>`_
|
||||
chapter. The legacy firewall is still available for versions before
|
||||
1.4-rolling-202308040557 and can be found in the :ref:`firewall-legacy`
|
||||
1.4-rolling-202308040557 and can be found in the :ref:`legacy-firewall`
|
||||
chapter. The examples in this section use the legacy firewall configuration
|
||||
commands, since this feature has been removed in earlier releases.
|
||||
|
||||
@ -145,7 +145,7 @@ To add logging to the default rule, do:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall name <ruleSet> enable-default-log
|
||||
set firewall name <ruleSet> default-log
|
||||
|
||||
|
||||
By default, iptables does not allow traffic for established sessions to
|
||||
@ -251,7 +251,7 @@ Since we have 4 zones, we need to setup the following rulesets.
|
||||
Dmz-local
|
||||
|
||||
Even if the two zones will never communicate, it is a good idea to
|
||||
create the zone-pair-direction rulesets and set enable-default-log. This
|
||||
create the zone-pair-direction rulesets and set default-log. This
|
||||
will allow you to log attempts to access the networks. Without it, you
|
||||
will never see the connection attempts.
|
||||
|
||||
@ -261,7 +261,7 @@ This is an example of the three base rules.
|
||||
|
||||
name wan-lan {
|
||||
default-action drop
|
||||
enable-default-log
|
||||
default-log
|
||||
rule 1 {
|
||||
action accept
|
||||
state {
|
||||
@ -285,7 +285,7 @@ Here is an example of an IPv6 DMZ-WAN ruleset.
|
||||
|
||||
ipv6-name dmz-wan-6 {
|
||||
default-action drop
|
||||
enable-default-log
|
||||
default-log
|
||||
rule 1 {
|
||||
action accept
|
||||
state {
|
||||
|
||||
@ -11,43 +11,68 @@ a deamonless container engine.
|
||||
Configuration
|
||||
*************
|
||||
|
||||
.. cfgcmd:: set container name <name> image
|
||||
|
||||
.. cfgcmd:: set container name <name> image
|
||||
|
||||
Sets the image name in the hub registry
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set container name mysql-server image mysql:8.0
|
||||
|
||||
If a registry is not specified, Docker.io will be used as the container
|
||||
registry unless an alternative registry is specified using
|
||||
**set container registry <name>** or the registry is included in the image name
|
||||
If a registry is not specified, Docker.io will be used as the container
|
||||
registry unless an alternative registry is specified using
|
||||
**set container registry <name>** or the registry is included
|
||||
in the image name
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set container name mysql-server image quay.io/mysql:8.0
|
||||
|
||||
.. cfgcmd:: set container name <name> entrypoint <entrypoint>
|
||||
|
||||
Override the default entrypoint from the image for a container.
|
||||
|
||||
.. cfgcmd:: set container name <name> command <command>
|
||||
|
||||
Override the default command from the image for a container.
|
||||
|
||||
.. cfgcmd:: set container name <name> arguments <arguments>
|
||||
|
||||
Set the command arguments for a container.
|
||||
|
||||
.. cfgcmd:: set container name <name> host-name <hostname>
|
||||
|
||||
Set the host name for a container.
|
||||
|
||||
.. cfgcmd:: set container name <name> allow-host-pid
|
||||
|
||||
The container and the host share the same process namespace.
|
||||
This means that processes running on the host are visible inside the
|
||||
container, and processes inside the container are visible on the host.
|
||||
|
||||
The command translates to "--pid host" when the container is created.
|
||||
|
||||
.. cfgcmd:: set container name <name> allow-host-networks
|
||||
|
||||
Allow host networking in a container. The network stack of the container is
|
||||
|
||||
Allow host networking in a container. The network stack of the container is
|
||||
not isolated from the host and will use the host IP.
|
||||
|
||||
The following commands translate to "--net host" when the container
|
||||
is created
|
||||
The command translates to "--net host" when the container is created.
|
||||
|
||||
.. note:: **allow-host-networks** cannot be used with **network**
|
||||
|
||||
.. cfgcmd:: set container name <name> network <networkname>
|
||||
.. cfgcmd:: set container name <name> network <networkname>
|
||||
|
||||
Attaches user-defined network to a container.
|
||||
Only one network must be specified and must already exist.
|
||||
|
||||
.. cfgcmd:: set container name <name> network <networkname> address <address>
|
||||
.. cfgcmd:: set container name <name> network <networkname> address <address>
|
||||
|
||||
Optionally set a specific static IPv4 or IPv6 address for the container.
|
||||
This address must be within the named network prefix.
|
||||
|
||||
.. note:: The first IP in the container network is reserved by the engine and cannot be used
|
||||
.. note:: The first IP in the container network is reserved by the
|
||||
engine and cannot be used
|
||||
|
||||
.. cfgcmd:: set container name <name> description <text>
|
||||
|
||||
@ -58,7 +83,7 @@ Configuration
|
||||
Add custom environment variables.
|
||||
Multiple environment variables are allowed.
|
||||
The following commands translate to "-e key=value" when the container
|
||||
is created.
|
||||
is created.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
@ -88,23 +113,41 @@ Configuration
|
||||
|
||||
set container name coredns volume 'corefile' source /config/coredns/Corefile
|
||||
set container name coredns volume 'corefile' destination /etc/Corefile
|
||||
|
||||
|
||||
.. cfgcmd:: set container name <name> volume <volumename> mode <ro | rw>
|
||||
|
||||
Volume is either mounted as rw (read-write - default) or ro (read-only)
|
||||
|
||||
.. cfgcmd:: set container name <name> uid <number>
|
||||
.. cfgcmd:: set container name <name> gid <number>
|
||||
|
||||
Set the User ID or Group ID of the container
|
||||
|
||||
.. cfgcmd:: set container name <name> restart [no | on-failure | always]
|
||||
|
||||
Set the restart behavior of the container.
|
||||
|
||||
- **no**: Do not restart containers on exit
|
||||
- **on-failure**: Restart containers when they exit with a non-zero exit code, retrying indefinitely (default)
|
||||
- **always**: Restart containers when they exit, regardless of status, retrying indefinitely
|
||||
- **on-failure**: Restart containers when they exit with a non-zero
|
||||
exit code, retrying indefinitely (default)
|
||||
- **always**: Restart containers when they exit, regardless of status,
|
||||
retrying indefinitely
|
||||
|
||||
.. cfgcmd:: set container name <name> cpu-quota <num>
|
||||
|
||||
This specifies the number of CPU resources the container can use.
|
||||
|
||||
Default is 0 for unlimited.
|
||||
For example, 1.25 limits the container to use up to 1.25 cores
|
||||
worth of CPU time.
|
||||
This can be a decimal number with up to three decimal places.
|
||||
|
||||
The command translates to "--cpus=<num>" when the container is created.
|
||||
|
||||
.. cfgcmd:: set container name <name> memory <MB>
|
||||
|
||||
|
||||
Constrain the memory available to the container.
|
||||
|
||||
|
||||
Default is 512 MB. Use 0 MB for unlimited memory.
|
||||
|
||||
.. cfgcmd:: set container name <name> device <devicename> source <path>
|
||||
@ -112,30 +155,67 @@ Configuration
|
||||
|
||||
Add a host device to the container.
|
||||
|
||||
.. cfgcmd:: container name <name> cap-add <text>
|
||||
.. cfgcmd:: set container name <name> capability <text>
|
||||
|
||||
Set container capabilities or permissions.
|
||||
|
||||
- **net-admin**: Network operations (interface, firewall, routing tables)
|
||||
- **net-bind-service**: Bind a socket to privileged ports (port numbers less than 1024)
|
||||
- **net-bind-service**: Bind a socket to privileged ports
|
||||
(port numbers less than 1024)
|
||||
- **net-raw**: Permission to create raw network sockets
|
||||
- **setpcap**: Capability sets (from bounded or inherited set)
|
||||
- **sys-admin**: Administation operations (quotactl, mount, sethostname, setdomainame)
|
||||
- **sys-admin**: Administration operations (quotactl, mount, sethostname,
|
||||
setdomainame)
|
||||
- **sys-time**: Permission to set system clock
|
||||
|
||||
.. cfgcmd:: set container name <name> label <label> value <value>
|
||||
|
||||
Add metadata label for this container.
|
||||
|
||||
.. cfgcmd:: set container name <name> disable
|
||||
|
||||
|
||||
Disable a container.
|
||||
|
||||
.. cfgcmd:: set container network <networkname>
|
||||
Container Networks
|
||||
==================
|
||||
|
||||
.. cfgcmd:: set container network <name>
|
||||
|
||||
Creates a named container network
|
||||
|
||||
.. cfgcmd:: set container network <name> description
|
||||
|
||||
A brief description what this network is all about.
|
||||
|
||||
.. cfgcmd:: set container network <name> prefix <ipv4|ipv6>
|
||||
|
||||
Define IPv4 and/or IPv6 prefix for a given network name.
|
||||
Both IPv4 and IPv6 can be used in parallel.
|
||||
|
||||
.. cfgcmd:: set container network <name> vrf <nme>
|
||||
|
||||
Bind container network to a given VRF instance.
|
||||
|
||||
Container Registry
|
||||
==================
|
||||
|
||||
.. cfgcmd:: set container registry <name>
|
||||
|
||||
Adds registry to list of unqualified-search-registries. By default, for any
|
||||
image that does not include the registry in the image name, Vyos will use
|
||||
docker.io as the container registry.
|
||||
image that does not include the registry in the image name, VyOS will use
|
||||
docker.io and quay.io as the container registry.
|
||||
|
||||
.. cfgcmd:: set container registry <name> disable
|
||||
|
||||
Disable a given container registry
|
||||
|
||||
.. cfgcmd:: set container registry <name> authentication username
|
||||
.. cfgcmd:: set container registry <name> authentication password
|
||||
|
||||
Some container registries require credentials to be used.
|
||||
|
||||
Credentials can be defined here and will only be used when adding a
|
||||
container image to the system.
|
||||
|
||||
|
||||
******************
|
||||
@ -143,7 +223,7 @@ Operation Commands
|
||||
******************
|
||||
|
||||
.. opcmd:: add container image <containername>
|
||||
|
||||
|
||||
Pull a new image for container
|
||||
|
||||
.. opcmd:: show container
|
||||
@ -151,7 +231,7 @@ Operation Commands
|
||||
Show the list of all active containers.
|
||||
|
||||
.. opcmd:: show container image
|
||||
|
||||
|
||||
Show the local container images.
|
||||
|
||||
.. opcmd:: show container log <containername>
|
||||
@ -170,34 +250,38 @@ Operation Commands
|
||||
|
||||
Update container image
|
||||
|
||||
.. opcmd:: delete container image [image id|all]
|
||||
|
||||
Delete a particular container image based on it's image ID.
|
||||
You can also delete all container images at once.
|
||||
|
||||
*********************
|
||||
Example Configuration
|
||||
*********************
|
||||
|
||||
For the sake of demonstration, `example #1 in the official documentation
|
||||
<https://www.zabbix.com/documentation/current/manual/installation/containers>`_
|
||||
<https://www.zabbix.com/documentation/current/manual/
|
||||
installation/containers>`_
|
||||
to the declarative VyOS CLI syntax.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set container network zabbix-net prefix 172.20.0.0/16
|
||||
set container network zabbix-net description 'Network for Zabbix component containers'
|
||||
set container network zabbix prefix 172.20.0.0/16
|
||||
set container network zabbix description 'Network for Zabbix component containers'
|
||||
|
||||
set container name mysql-server image mysql:8.0
|
||||
set container name mysql-server network zabbix-net
|
||||
set container name mysql-server network zabbix
|
||||
|
||||
set container name mysql-server environment 'MYSQL_DATABASE' value 'zabbix'
|
||||
set container name mysql-server environment 'MYSQL_USER' value 'zabbix'
|
||||
set container name mysql-server environment 'MYSQL_PASSWORD' value 'zabbix_pwd'
|
||||
set container name mysql-server environment 'MYSQL_ROOT_PASSWORD' value 'root_pwd'
|
||||
set container name mysql-server environment 'MYSQL_ROOT_PASSWORD' value 'root_pwd'
|
||||
|
||||
set container name zabbix-java-gateway image zabbix/zabbix-java-gateway:alpine-5.2-latest
|
||||
set container name zabbix-java-gateway network zabbix-net
|
||||
set container name zabbix-java-gateway network zabbix
|
||||
|
||||
set container name zabbix-server-mysql image zabbix/zabbix-server-mysql:alpine-5.2-latest
|
||||
set container name zabbix-server-mysql network zabbix-net
|
||||
set container name zabbix-server-mysql network zabbix
|
||||
|
||||
set container name zabbix-server-mysql environment 'DB_SERVER_HOST' value 'mysql-server'
|
||||
set container name zabbix-server-mysql environment 'MYSQL_DATABASE' value 'zabbix'
|
||||
@ -210,7 +294,7 @@ Example Configuration
|
||||
set container name zabbix-server-mysql port zabbix destination 10051
|
||||
|
||||
set container name zabbix-web-nginx-mysql image zabbix/zabbix-web-nginx-mysql:alpine-5.2-latest
|
||||
set container name zabbix-web-nginx-mysql network zabbix-net
|
||||
set container name zabbix-web-nginx-mysql network zabbix
|
||||
|
||||
set container name zabbix-web-nginx-mysql environment 'MYSQL_DATABASE' value 'zabbix'
|
||||
set container name zabbix-web-nginx-mysql environment 'ZBX_SERVER_HOST' value 'zabbix-server-mysql'
|
||||
|
||||
401
docs/configuration/firewall/bridge.rst
Normal file
@ -0,0 +1,401 @@
|
||||
:lastproofread: 2023-11-08
|
||||
|
||||
.. _firewall-configuration:
|
||||
|
||||
#############################
|
||||
Bridge Firewall Configuration
|
||||
#############################
|
||||
|
||||
.. note:: **Documentation under development**
|
||||
|
||||
********
|
||||
Overview
|
||||
********
|
||||
|
||||
In this section there's useful information of all firewall configuration that
|
||||
can be done regarding bridge, and appropiate op-mode commands.
|
||||
Configuration commands covered in this section:
|
||||
|
||||
.. cfgcmd:: set firewall bridge ...
|
||||
|
||||
From main structure defined in :doc:`Firewall Overview</configuration/firewall/index>`
|
||||
in this section you can find detailed information only for the next part
|
||||
of the general structure:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
- set firewall
|
||||
* bridge
|
||||
- forward
|
||||
+ filter
|
||||
- name
|
||||
+ custom_name
|
||||
|
||||
Traffic which is received by the router on an interface which is member of a
|
||||
bridge is processed on the **Bridge Layer**. A simplified packet flow diagram
|
||||
for this layer is shown next:
|
||||
|
||||
.. figure:: /_static/images/firewall-bridge-packet-flow.png
|
||||
|
||||
For traffic that needs to be forwared internally by the bridge, base chain is
|
||||
is **forward**, and it's base command for filtering is ``set firewall bridge
|
||||
forward filter ...``, which happens in stage 4, highlightened with red color.
|
||||
|
||||
Custom bridge firewall chains can be create with command ``set firewall bridge
|
||||
name <name> ...``. In order to use such custom chain, a rule with action jump,
|
||||
and the appropiate target should be defined in a base chain.
|
||||
|
||||
.. note:: **Layer 3 bridge**:
|
||||
When an IP address is assigned to the bridge interface, and if traffic
|
||||
is sent to the router to this IP (for example using such IP as
|
||||
default gateway), then rules defined for **bridge firewall** won't
|
||||
match, and firewall analysis continues at **IP layer**.
|
||||
|
||||
************
|
||||
Bridge Rules
|
||||
************
|
||||
|
||||
For firewall filtering, firewall rules needs to be created. Each rule is
|
||||
numbered, has an action to apply if the rule is matched, and the ability
|
||||
to specify multiple criteria matchers. Data packets go through the rules
|
||||
from 1 - 999999, so order is crucial. At the first match the action of the
|
||||
rule will be executed.
|
||||
|
||||
Actions
|
||||
=======
|
||||
|
||||
If a rule is defined, then an action must be defined for it. This tells the
|
||||
firewall what to do if all criteria matchers defined for such rule do match.
|
||||
|
||||
In firewall bridge rules, the action can be:
|
||||
|
||||
* ``accept``: accept the packet.
|
||||
|
||||
* ``continue``: continue parsing next rule.
|
||||
|
||||
* ``drop``: drop the packet.
|
||||
|
||||
* ``jump``: jump to another custom chain.
|
||||
|
||||
* ``return``: Return from the current chain and continue at the next rule
|
||||
of the last chain.
|
||||
|
||||
* ``queue``: Enqueue packet to userspace.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999> action
|
||||
[accept | continue | drop | jump | queue | return]
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999> action
|
||||
[accept | continue | drop | jump | queue | return]
|
||||
|
||||
This required setting defines the action of the current rule. If action is
|
||||
set to jump, then jump-target is also needed.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
jump-target <text>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
jump-target <text>
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
queue <0-65535>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
queue <0-65535>
|
||||
|
||||
To be used only when action is set to ``queue``. Use this command to specify
|
||||
queue target to use. Queue range is also supported.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
queue-options bypass
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
queue-options bypass
|
||||
|
||||
To be used only when action is set to ``queue``. Use this command to let
|
||||
packet go through firewall when no userspace software is connected to the
|
||||
queue.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
queue-options fanout
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
queue-options fanout
|
||||
|
||||
To be used only when action is set to ``queue``. Use this command to
|
||||
distribute packets between several queues.
|
||||
|
||||
Also, **default-action** is an action that takes place whenever a packet does
|
||||
not match any rule in it's chain. For base chains, possible options for
|
||||
**default-action** are **accept** or **drop**.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter default-action
|
||||
[accept | drop]
|
||||
.. cfgcmd:: set firewall bridge name <name> default-action
|
||||
[accept | continue | drop | jump | queue | return]
|
||||
|
||||
This set the default action of the rule-set if no rule matched a packet
|
||||
criteria. If default-action is set to ``jump``, then
|
||||
``default-jump-target`` is also needed. Note that for base chains, default
|
||||
action can only be set to ``accept`` or ``drop``, while on custom chain,
|
||||
more actions are available.
|
||||
|
||||
.. cfgcmd:: set firewall bridge name <name> default-jump-target <text>
|
||||
|
||||
To be used only when ``defult-action`` is set to ``jump``. Use this
|
||||
command to specify jump target for default rule.
|
||||
|
||||
.. note:: **Important note about default-actions:**
|
||||
If default action for any base chain is not defined, then the default
|
||||
action is set to **accept** for that chain. For custom chains, if default
|
||||
action is not defined, then the default-action is set to **drop**.
|
||||
|
||||
Firewall Logs
|
||||
=============
|
||||
|
||||
Logging can be enable for every single firewall rule. If enabled, other
|
||||
log options can be defined.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999> log
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999> log
|
||||
|
||||
Enable logging for the matched packet. If this configuration command is not
|
||||
present, then log is not enabled.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter default-log
|
||||
.. cfgcmd:: set firewall bridge name <name> default-log
|
||||
|
||||
Use this command to enable the logging of the default action on
|
||||
the specified chain.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
log-options level [emerg | alert | crit | err | warn | notice
|
||||
| info | debug]
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
log-options level [emerg | alert | crit | err | warn | notice
|
||||
| info | debug]
|
||||
|
||||
Define log-level. Only applicable if rule log is enable.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
log-options group <0-65535>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
log-options group <0-65535>
|
||||
|
||||
Define log group to send message to. Only applicable if rule log is enable.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
log-options snapshot-length <0-9000>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
log-options snapshot-length <0-9000>
|
||||
|
||||
Define length of packet payload to include in netlink message. Only
|
||||
applicable if rule log is enable and log group is defined.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
log-options queue-threshold <0-65535>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
log-options queue-threshold <0-65535>
|
||||
|
||||
Define number of packets to queue inside the kernel before sending them to
|
||||
userspace. Only applicable if rule log is enable and log group is defined.
|
||||
|
||||
Firewall Description
|
||||
====================
|
||||
|
||||
For reference, a description can be defined for every defined custom chain.
|
||||
|
||||
.. cfgcmd:: set firewall bridge name <name> description <text>
|
||||
|
||||
Provide a rule-set description to a custom firewall chain.
|
||||
|
||||
Rule Status
|
||||
===========
|
||||
|
||||
When defining a rule, it is enable by default. In some cases, it is useful to
|
||||
just disable the rule, rather than removing it.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999> disable
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999> disable
|
||||
|
||||
Command for disabling a rule but keep it in the configuration.
|
||||
|
||||
Matching criteria
|
||||
=================
|
||||
|
||||
There are a lot of matching criteria against which the packet can be tested.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
destination mac-address <mac-address>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
destination mac-address <mac-address>
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
source mac-address <mac-address>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
source mac-address <mac-address>
|
||||
|
||||
Match criteria based on source and/or destination mac-address.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
inbound-interface name <iface>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
inbound-interface name <iface>
|
||||
|
||||
Match based on inbound interface. Wilcard ``*`` can be used.
|
||||
For example: ``eth2*``. Prepending character ``!`` for inverted matching
|
||||
criteria is also supportd. For example ``!eth2``
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
inbound-interface group <iface_group>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
inbound-interface group <iface_group>
|
||||
|
||||
Match based on inbound interface group. Prepending character ``!`` for
|
||||
inverted matching criteria is also supportd. For example ``!IFACE_GROUP``
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
outbound-interface name <iface>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
outbound-interface name <iface>
|
||||
|
||||
Match based on outbound interface. Wilcard ``*`` can be used.
|
||||
For example: ``eth2*``. Prepending character ``!`` for inverted matching
|
||||
criteria is also supportd. For example ``!eth2``
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
outbound-interface group <iface_group>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
outbound-interface group <iface_group>
|
||||
|
||||
Match based on outbound interface group. Prepending character ``!`` for
|
||||
inverted matching criteria is also supportd. For example ``!IFACE_GROUP``
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
vlan id <0-4096>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
vlan id <0-4096>
|
||||
|
||||
Match based on vlan ID. Range is also supported.
|
||||
|
||||
.. cfgcmd:: set firewall bridge forward filter rule <1-999999>
|
||||
vlan priority <0-7>
|
||||
.. cfgcmd:: set firewall bridge name <name> rule <1-999999>
|
||||
vlan priority <0-7>
|
||||
|
||||
Match based on vlan priority(pcp). Range is also supported.
|
||||
|
||||
***********************
|
||||
Operation-mode Firewall
|
||||
***********************
|
||||
|
||||
Rule-set overview
|
||||
=================
|
||||
|
||||
In this section you can find all useful firewall op-mode commands.
|
||||
|
||||
General commands for firewall configuration, counter and statiscits:
|
||||
|
||||
.. opcmd:: show firewall
|
||||
.. opcmd:: show firewall summary
|
||||
.. opcmd:: show firewall statistics
|
||||
|
||||
And, to print only bridge firewall information:
|
||||
|
||||
.. opcmd:: show firewall bridge
|
||||
.. opcmd:: show firewall bridge forward filter
|
||||
.. opcmd:: show firewall bridge forward filter rule <rule>
|
||||
.. opcmd:: show firewall bridge name <name>
|
||||
.. opcmd:: show firewall bridge name <name> rule <rule>
|
||||
|
||||
Show Firewall log
|
||||
=================
|
||||
|
||||
.. opcmd:: show log firewall
|
||||
.. opcmd:: show log firewall bridge
|
||||
.. opcmd:: show log firewall bridge forward
|
||||
.. opcmd:: show log firewall bridge forward filter
|
||||
.. opcmd:: show log firewall bridge name <name>
|
||||
.. opcmd:: show log firewall bridge forward filter rule <rule>
|
||||
.. opcmd:: show log firewall bridge name <name> rule <rule>
|
||||
|
||||
Show the logs of all firewall; show all bridge firewall logs; show all logs
|
||||
for forward hook; show all logs for forward hook and priority filter; show
|
||||
all logs for particular custom chain; show logs for specific Rule-Set.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
Configuration example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall bridge forward filter default-action 'drop'
|
||||
set firewall bridge forward filter default-log
|
||||
set firewall bridge forward filter rule 10 action 'continue'
|
||||
set firewall bridge forward filter rule 10 inbound-interface name 'eth2'
|
||||
set firewall bridge forward filter rule 10 vlan id '22'
|
||||
set firewall bridge forward filter rule 20 action 'drop'
|
||||
set firewall bridge forward filter rule 20 inbound-interface group 'TRUNK-RIGHT'
|
||||
set firewall bridge forward filter rule 20 vlan id '60'
|
||||
set firewall bridge forward filter rule 30 action 'jump'
|
||||
set firewall bridge forward filter rule 30 jump-target 'TEST'
|
||||
set firewall bridge forward filter rule 30 outbound-interface name '!eth1'
|
||||
set firewall bridge forward filter rule 35 action 'accept'
|
||||
set firewall bridge forward filter rule 35 vlan id '11'
|
||||
set firewall bridge forward filter rule 40 action 'continue'
|
||||
set firewall bridge forward filter rule 40 destination mac-address '66:55:44:33:22:11'
|
||||
set firewall bridge forward filter rule 40 source mac-address '11:22:33:44:55:66'
|
||||
set firewall bridge name TEST default-action 'accept'
|
||||
set firewall bridge name TEST default-log
|
||||
set firewall bridge name TEST rule 10 action 'continue'
|
||||
set firewall bridge name TEST rule 10 log
|
||||
set firewall bridge name TEST rule 10 vlan priority '0'
|
||||
|
||||
And op-mode commands:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@BRI:~$ show firewall bridge
|
||||
Rulesets bridge Information
|
||||
|
||||
---------------------------------
|
||||
bridge Firewall "forward filter"
|
||||
|
||||
Rule Action Protocol Packets Bytes Conditions
|
||||
------- -------- ---------- --------- ------- ---------------------------------------------------------------------
|
||||
10 continue all 0 0 iifname "eth2" vlan id 22 continue
|
||||
20 drop all 0 0 iifname @I_TRUNK-RIGHT vlan id 60
|
||||
30 jump all 2130 170688 oifname != "eth1" jump NAME_TEST
|
||||
35 accept all 2080 168616 vlan id 11 accept
|
||||
40 continue all 0 0 ether daddr 66:55:44:33:22:11 ether saddr 11:22:33:44:55:66 continue
|
||||
default drop all 0 0
|
||||
|
||||
---------------------------------
|
||||
bridge Firewall "name TEST"
|
||||
|
||||
Rule Action Protocol Packets Bytes Conditions
|
||||
------- -------- ---------- --------- ------- --------------------------------------------------
|
||||
10 continue all 2130 170688 vlan pcp 0 prefix "[bri-NAM-TEST-10-C]" continue
|
||||
default accept all 2130 170688
|
||||
|
||||
vyos@BRI:~$
|
||||
vyos@BRI:~$ show firewall bridge name TEST
|
||||
Ruleset Information
|
||||
|
||||
---------------------------------
|
||||
bridge Firewall "name TEST"
|
||||
|
||||
Rule Action Protocol Packets Bytes Conditions
|
||||
------- -------- ---------- --------- ------- --------------------------------------------------
|
||||
10 continue all 2130 170688 vlan pcp 0 prefix "[bri-NAM-TEST-10-C]" continue
|
||||
default accept all 2130 170688
|
||||
|
||||
vyos@BRI:~$
|
||||
|
||||
Inspect logs:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@BRI:~$ show log firewall bridge
|
||||
Dec 05 14:37:47 kernel: [bri-NAM-TEST-10-C]IN=eth1 OUT=eth2 ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=50:00:00:04:00:00 IPSRC=10.11.11.101 MACDST=00:00:00:00:00:00 IPDST=10.11.11.102
|
||||
Dec 05 14:37:48 kernel: [bri-NAM-TEST-10-C]IN=eth1 OUT=eth2 ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=50:00:00:04:00:00 IPSRC=10.11.11.101 MACDST=00:00:00:00:00:00 IPDST=10.11.11.102
|
||||
Dec 05 14:37:49 kernel: [bri-NAM-TEST-10-C]IN=eth1 OUT=eth2 ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=50:00:00:04:00:00 IPSRC=10.11.11.101 MACDST=00:00:00:00:00:00 IPDST=10.11.11.102
|
||||
...
|
||||
vyos@BRI:~$ show log firewall bridge forward filter
|
||||
Dec 05 14:42:22 kernel: [bri-FWD-filter-default-D]IN=eth2 OUT=eth1 MAC=33:33:00:00:00:16:50:00:00:06:00:00:86:dd SRC=0000:0000:0000:0000:0000:0000:0000:0000 DST=ff02:0000:0000:0000:0000:0000:0000:0016 LEN=96 TC=0 HOPLIMIT=1 FLOWLBL=0 PROTO=ICMPv6 TYPE=143 CODE=0
|
||||
Dec 05 14:42:22 kernel: [bri-FWD-filter-default-D]IN=eth2 OUT=eth1 MAC=33:33:00:00:00:16:50:00:00:06:00:00:86:dd SRC=0000:0000:0000:0000:0000:0000:0000:0000 DST=ff02:0000:0000:0000:0000:0000:0000:0016 LEN=96 TC=0 HOPLIMIT=1 FLOWLBL=0 PROTO=ICMPv6 TYPE=143 CODE=0
|
||||
189
docs/configuration/firewall/flowtables.rst
Normal file
@ -0,0 +1,189 @@
|
||||
:lastproofread: 2023-12-26
|
||||
|
||||
.. _firewall-flowtables-configuration:
|
||||
|
||||
#################################
|
||||
Flowtables Firewall Configuration
|
||||
#################################
|
||||
|
||||
.. note:: **Documentation under development**
|
||||
|
||||
********
|
||||
Overview
|
||||
********
|
||||
|
||||
In this section there's useful information of all firewall configuration that
|
||||
can be done regarding flowtables.
|
||||
|
||||
.. cfgcmd:: set firewall flowtables ...
|
||||
|
||||
From main structure defined in
|
||||
:doc:`Firewall Overview</configuration/firewall/index>`
|
||||
in this section you can find detailed information only for the next part
|
||||
of the general structure:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
- set firewall
|
||||
* flowtable
|
||||
- custom_flow_table
|
||||
+ ...
|
||||
|
||||
|
||||
Flowtables allows you to define a fastpath through the flowtable datapath.
|
||||
The flowtable supports for the layer 3 IPv4 and IPv6 and the layer 4 TCP
|
||||
and UDP protocols.
|
||||
|
||||
.. figure:: /_static/images/firewall-flowtable-packet-flow.png
|
||||
|
||||
Once the first packet of the flow successfully goes through the IP forwarding
|
||||
path (black circles path), from the second packet on, you might decide to
|
||||
offload the flow to the flowtable through your ruleset. The flowtable
|
||||
infrastructure provides a rule action that allows you to specify when to add
|
||||
a flow to the flowtable (On forward filtering, red circle number 6)
|
||||
|
||||
A packet that finds a matching entry in the flowtable (flowtable hit) is
|
||||
transmitted to the output netdevice, hence, packets bypass the classic IP
|
||||
forwarding path and uses the **Fast Path** (orange circles path). The visible
|
||||
effect is that you do not see these packets from any of the Netfilter
|
||||
hooks coming after ingress. In case that there is no matching entry in the
|
||||
flowtable (flowtable miss), the packet follows the classic IP forwarding path.
|
||||
|
||||
.. note:: **Flowtable Reference:**
|
||||
https://docs.kernel.org/networking/nf_flowtable.html
|
||||
|
||||
|
||||
***********************
|
||||
Flowtable Configuration
|
||||
***********************
|
||||
|
||||
In order to use flowtables, the minimal configuration needed includes:
|
||||
|
||||
* Create flowtable: create flowtable, which includes the interfaces
|
||||
that are going to be used by the flowtable.
|
||||
|
||||
* Create firewall rule: create a firewall rule, setting action to
|
||||
``offload`` and using desired flowtable for ``offload-target``.
|
||||
|
||||
Creating a flow table:
|
||||
|
||||
.. cfgcmd:: set firewall flowtable <flow_table_name> interface <iface>
|
||||
|
||||
Define interfaces to be used in the flowtable.
|
||||
|
||||
.. cfgcmd:: set firewall flowtable <flow_table_name> description <text>
|
||||
|
||||
Provide a description to the flow table.
|
||||
|
||||
.. cfgcmd:: set firewall flowtable <flow_table_name> offload
|
||||
<hardware | software>
|
||||
|
||||
Define type of offload to be used by the flowtable: ``hardware`` or
|
||||
``software``. By default, ``software`` offload is used.
|
||||
|
||||
.. note:: **Hardware offload:** should be supported by the NICs used.
|
||||
|
||||
Creating rules for using flow tables:
|
||||
|
||||
.. cfgcmd:: set firewall [ipv4 | ipv4] forward filter rule <1-999999>
|
||||
action offload
|
||||
|
||||
Create firewall rule in forward chain, and set action to ``offload``.
|
||||
|
||||
.. cfgcmd:: set firewall [ipv4 | ipv4] forward filter rule <1-999999>
|
||||
offload-target <flowtable>
|
||||
|
||||
Create firewall rule in forward chain, and define which flowtbale
|
||||
should be used. Only applicable if action is ``offload``.
|
||||
|
||||
*********************
|
||||
Configuration Example
|
||||
*********************
|
||||
|
||||
Things to be considred in this setup:
|
||||
|
||||
* Two interfaces are going to be used in the flowtables: eth0 and eth1
|
||||
|
||||
* Minumum firewall ruleset is provided, which includes some filtering rules,
|
||||
and appropiate rules for using flowtable offload capabilities.
|
||||
|
||||
As described, first packet will be evaluated by all the firewall path, so
|
||||
desired connection should be explicitely accepted. Same thing should be taken
|
||||
into account for traffic in reverse order. In most cases state policies are
|
||||
used in order to accept connection in reverse patch.
|
||||
|
||||
We will only accept traffic comming from interface eth0, protocol tcp and
|
||||
destination port 1122. All other traffic traspassing the router should be
|
||||
blocked.
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall flowtable FT01 interface 'eth0'
|
||||
set firewall flowtable FT01 interface 'eth1'
|
||||
set firewall ipv4 forward filter default-action 'drop'
|
||||
set firewall ipv4 forward filter rule 10 action 'offload'
|
||||
set firewall ipv4 forward filter rule 10 offload-target 'FT01'
|
||||
set firewall ipv4 forward filter rule 10 state 'established'
|
||||
set firewall ipv4 forward filter rule 10 state 'related'
|
||||
set firewall ipv4 forward filter rule 20 action 'accept'
|
||||
set firewall ipv4 forward filter rule 20 state 'established'
|
||||
set firewall ipv4 forward filter rule 20 state 'related'
|
||||
set firewall ipv4 forward filter rule 110 action 'accept'
|
||||
set firewall ipv4 forward filter rule 110 destination address '192.0.2.100'
|
||||
set firewall ipv4 forward filter rule 110 destination port '1122'
|
||||
set firewall ipv4 forward filter rule 110 inbound-interface name 'eth0'
|
||||
set firewall ipv4 forward filter rule 110 protocol 'tcp'
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
Analysis on what happens for desired connection:
|
||||
|
||||
1. First packet is received on eht0, with destination address 192.0.2.100,
|
||||
protocol tcp and destination port 1122. Assume such destination address is
|
||||
reachable through interface eth1.
|
||||
|
||||
2. Since this is the first packet, connection status of this connection,
|
||||
so far is **new**. So neither rule 10 nor 20 are valid.
|
||||
|
||||
3. Rule 110 is hit, so connection is accepted.
|
||||
|
||||
4. Once answer from server 192.0.2.100 is seen in opposite direction,
|
||||
connection state will be triggered to **established**, so this reply is
|
||||
accepted in rule 20.
|
||||
|
||||
5. Second packet for this connection is received by the router. Since
|
||||
connection state is **established**, then rule 10 is hit, and a new entry
|
||||
in the flowtable FT01 is added for this connection.
|
||||
|
||||
6. All subsecuent packets will skip traditional path, and will be offloaded
|
||||
and will use the **Fast Path**.
|
||||
|
||||
Checks
|
||||
------
|
||||
|
||||
It's time to check conntrack table, to see if any connection was accepted,
|
||||
and if was properly offloaded
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@FlowTables:~$ show firewall ipv4 forward filter
|
||||
Ruleset Information
|
||||
|
||||
---------------------------------
|
||||
ipv4 Firewall "forward filter"
|
||||
|
||||
Rule Action Protocol Packets Bytes Conditions
|
||||
------- -------- ---------- --------- ------- ----------------------------------------------------------------
|
||||
10 offload all 8 468 ct state { established, related } flow add @VYOS_FLOWTABLE_FT01
|
||||
20 accept all 8 468 ct state { established, related } accept
|
||||
110 accept tcp 2 120 ip daddr 192.0.2.100 tcp dport 1122 iifname "eth0" accept
|
||||
default drop all 7 420
|
||||
|
||||
vyos@FlowTables:~$ sudo conntrack -L | grep tcp
|
||||
conntrack v1.4.6 (conntrack-tools): 5 flow entries have been shown.
|
||||
tcp 6 src=198.51.100.100 dst=192.0.2.100 sport=41676 dport=1122 src=192.0.2.100 dst=198.51.100.100 sport=1122 dport=41676 [OFFLOAD] mark=0 use=2
|
||||
vyos@FlowTables:~$
|
||||
147
docs/configuration/firewall/global-options.rst
Normal file
@ -0,0 +1,147 @@
|
||||
:lastproofread: 2023-12-26
|
||||
|
||||
.. _firewall-global-options-configuration:
|
||||
|
||||
#####################################
|
||||
Global Options Firewall Configuration
|
||||
#####################################
|
||||
|
||||
********
|
||||
Overview
|
||||
********
|
||||
|
||||
Some firewall settings are global and have an affect on the whole system.
|
||||
In this section there's useful information about these global-options that can
|
||||
be configured using vyos cli.
|
||||
|
||||
Configuration commands covered in this section:
|
||||
|
||||
.. cfgcmd:: set firewall global-options ...
|
||||
|
||||
*************
|
||||
Configuration
|
||||
*************
|
||||
|
||||
.. cfgcmd:: set firewall global-options all-ping [enable | disable]
|
||||
|
||||
By default, when VyOS receives an ICMP echo request packet destined for
|
||||
itself, it will answer with an ICMP echo reply, unless you avoid it
|
||||
through its firewall.
|
||||
|
||||
With the firewall you can set rules to accept, drop or reject ICMP in,
|
||||
out or local traffic. You can also use the general **firewall all-ping**
|
||||
command. This command affects only to LOCAL (packets destined for your
|
||||
VyOS system), not to IN or OUT traffic.
|
||||
|
||||
.. note:: **firewall global-options all-ping** affects only to LOCAL
|
||||
and it always behaves in the most restrictive way
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall global-options all-ping enable
|
||||
|
||||
When the command above is set, VyOS will answer every ICMP echo request
|
||||
addressed to itself, but that will only happen if no other rule is
|
||||
applied dropping or rejecting local echo requests. In case of conflict,
|
||||
VyOS will not answer ICMP echo requests.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall global-options all-ping disable
|
||||
|
||||
When the command above is set, VyOS will answer no ICMP echo request
|
||||
addressed to itself at all, no matter where it comes from or whether
|
||||
more specific rules are being applied to accept them.
|
||||
|
||||
.. cfgcmd:: set firewall global-options broadcast-ping [enable | disable]
|
||||
|
||||
This setting enable or disable the response of icmp broadcast
|
||||
messages. The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.icmp_echo_ignore_broadcasts``
|
||||
|
||||
.. cfgcmd:: set firewall global-options ip-src-route [enable | disable]
|
||||
.. cfgcmd:: set firewall global-options ipv6-src-route [enable | disable]
|
||||
|
||||
This setting handle if VyOS accept packets with a source route
|
||||
option. The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.conf.all.accept_source_route``
|
||||
* ``net.ipv6.conf.all.accept_source_route``
|
||||
|
||||
.. cfgcmd:: set firewall global-options receive-redirects [enable | disable]
|
||||
.. cfgcmd:: set firewall global-options ipv6-receive-redirects
|
||||
[enable | disable]
|
||||
|
||||
enable or disable of ICMPv4 or ICMPv6 redirect messages accepted
|
||||
by VyOS. The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.conf.all.accept_redirects``
|
||||
* ``net.ipv6.conf.all.accept_redirects``
|
||||
|
||||
.. cfgcmd:: set firewall global-options send-redirects [enable | disable]
|
||||
|
||||
enable or disable ICMPv4 redirect messages send by VyOS
|
||||
The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.conf.all.send_redirects``
|
||||
|
||||
.. cfgcmd:: set firewall global-options log-martians [enable | disable]
|
||||
|
||||
enable or disable the logging of martian IPv4 packets.
|
||||
The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.conf.all.log_martians``
|
||||
|
||||
.. cfgcmd:: set firewall global-options source-validation
|
||||
[strict | loose | disable]
|
||||
|
||||
Set the IPv4 source validation mode.
|
||||
The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.conf.all.rp_filter``
|
||||
|
||||
.. cfgcmd:: set firewall global-options syn-cookies [enable | disable]
|
||||
|
||||
Enable or Disable if VyOS use IPv4 TCP SYN Cookies.
|
||||
The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.tcp_syncookies``
|
||||
|
||||
.. cfgcmd:: set firewall global-options twa-hazards-protection
|
||||
[enable | disable]
|
||||
|
||||
Enable or Disable VyOS to be :rfc:`1337` conform.
|
||||
The following system parameter will be altered:
|
||||
|
||||
* ``net.ipv4.tcp_rfc1337``
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy established action
|
||||
[accept | drop | reject]
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy established log
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy established log-level
|
||||
[emerg | alert | crit | err | warn | notice | info | debug]
|
||||
|
||||
Set the global setting for an established connection.
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy invalid action
|
||||
[accept | drop | reject]
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy invalid log
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy invalid log-level
|
||||
[emerg | alert | crit | err | warn | notice | info | debug]
|
||||
|
||||
Set the global setting for invalid packets.
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy related action
|
||||
[accept | drop | reject]
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy related log
|
||||
|
||||
.. cfgcmd:: set firewall global-options state-policy related log-level
|
||||
[emerg | alert | crit | err | warn | notice | info | debug]
|
||||
|
||||
Set the global setting for related connections.
|
||||
429
docs/configuration/firewall/groups.rst
Normal file
@ -0,0 +1,429 @@
|
||||
:lastproofread: 2023-11-08
|
||||
|
||||
.. _firewall-groups-configuration:
|
||||
|
||||
###############
|
||||
Firewall groups
|
||||
###############
|
||||
|
||||
*************
|
||||
Configuration
|
||||
*************
|
||||
|
||||
Firewall groups represent collections of IP addresses, networks, ports,
|
||||
mac addresses, domains or interfaces. Once created, a group can be referenced
|
||||
by firewall, nat and policy route rules as either a source or destination
|
||||
matcher, and/or as inbound/outbound in the case of interface group.
|
||||
|
||||
Address Groups
|
||||
==============
|
||||
|
||||
In an **address group** a single IP address or IP address ranges are
|
||||
defined.
|
||||
|
||||
.. cfgcmd:: set firewall group address-group <name> address [address |
|
||||
address range]
|
||||
.. cfgcmd:: set firewall group ipv6-address-group <name> address <address>
|
||||
|
||||
Define a IPv4 or a IPv6 address group
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group address-group ADR-INSIDE-v4 address 192.168.0.1
|
||||
set firewall group address-group ADR-INSIDE-v4 address 10.0.0.1-10.0.0.8
|
||||
set firewall group ipv6-address-group ADR-INSIDE-v6 address 2001:db8::1
|
||||
|
||||
.. cfgcmd:: set firewall group address-group <name> description <text>
|
||||
.. cfgcmd:: set firewall group ipv6-address-group <name> description <text>
|
||||
|
||||
Provide a IPv4 or IPv6 address group description
|
||||
|
||||
Network Groups
|
||||
==============
|
||||
|
||||
While **network groups** accept IP networks in CIDR notation, specific
|
||||
IP addresses can be added as a 32-bit prefix. If you foresee the need
|
||||
to add a mix of addresses and networks, the network group is
|
||||
recommended.
|
||||
|
||||
.. cfgcmd:: set firewall group network-group <name> network <CIDR>
|
||||
.. cfgcmd:: set firewall group ipv6-network-group <name> network <CIDR>
|
||||
|
||||
Define a IPv4 or IPv6 Network group.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group network-group NET-INSIDE-v4 network 192.168.0.0/24
|
||||
set firewall group network-group NET-INSIDE-v4 network 192.168.1.0/24
|
||||
set firewall group ipv6-network-group NET-INSIDE-v6 network 2001:db8::/64
|
||||
|
||||
.. cfgcmd:: set firewall group network-group <name> description <text>
|
||||
.. cfgcmd:: set firewall group ipv6-network-group <name> description <text>
|
||||
|
||||
Provide an IPv4 or IPv6 network group description.
|
||||
|
||||
Interface Groups
|
||||
================
|
||||
|
||||
An **interface group** represents a collection of interfaces.
|
||||
|
||||
.. cfgcmd:: set firewall group interface-group <name> interface <text>
|
||||
|
||||
Define an interface group. Wildcard are accepted too.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group interface-group LAN interface bond1001
|
||||
set firewall group interface-group LAN interface eth3*
|
||||
|
||||
.. cfgcmd:: set firewall group interface-group <name> description <text>
|
||||
|
||||
Provide an interface group description
|
||||
|
||||
Port Groups
|
||||
===========
|
||||
|
||||
A **port group** represents only port numbers, not the protocol. Port
|
||||
groups can be referenced for either TCP or UDP. It is recommended that
|
||||
TCP and UDP groups are created separately to avoid accidentally
|
||||
filtering unnecessary ports. Ranges of ports can be specified by using
|
||||
`-`.
|
||||
|
||||
.. cfgcmd:: set firewall group port-group <name> port
|
||||
[portname | portnumber | startport-endport]
|
||||
|
||||
Define a port group. A port name can be any name defined in
|
||||
/etc/services. e.g.: http
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group port-group PORT-TCP-SERVER1 port http
|
||||
set firewall group port-group PORT-TCP-SERVER1 port 443
|
||||
set firewall group port-group PORT-TCP-SERVER1 port 5000-5010
|
||||
|
||||
.. cfgcmd:: set firewall group port-group <name> description <text>
|
||||
|
||||
Provide a port group description.
|
||||
|
||||
MAC Groups
|
||||
==========
|
||||
|
||||
A **mac group** represents a collection of mac addresses.
|
||||
|
||||
.. cfgcmd:: set firewall group mac-group <name> mac-address <mac-address>
|
||||
|
||||
Define a mac group.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group mac-group MAC-G01 mac-address 88:a4:c2:15:b6:4f
|
||||
set firewall group mac-group MAC-G01 mac-address 4c:d5:77:c0:19:81
|
||||
|
||||
.. cfgcmd:: set firewall group mac-group <name> description <text>
|
||||
|
||||
Provide a mac group description.
|
||||
|
||||
Domain Groups
|
||||
=============
|
||||
|
||||
A **domain group** represents a collection of domains.
|
||||
|
||||
.. cfgcmd:: set firewall group domain-group <name> address <domain>
|
||||
|
||||
Define a domain group.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group domain-group DOM address example.com
|
||||
|
||||
.. cfgcmd:: set firewall group domain-group <name> description <text>
|
||||
|
||||
Provide a domain group description.
|
||||
|
||||
Dynamic Groups
|
||||
==============
|
||||
|
||||
Firewall dynamic groups are different from all the groups defined previously
|
||||
because, not only they can be used as source/destination in firewall rules,
|
||||
but members of these groups are not defined statically using vyos
|
||||
configuration.
|
||||
|
||||
Instead, members of these groups are added dynamically using firewall
|
||||
rules.
|
||||
|
||||
Defining Dynamic Address Groups
|
||||
-------------------------------
|
||||
|
||||
Dynamic address group is supported by both IPv4 and IPv6 families.
|
||||
Commands used to define dynamic IPv4|IPv6 address groups are:
|
||||
|
||||
.. cfgcmd:: set firewall group dynamic-group address-group <name>
|
||||
.. cfgcmd:: set firewall group dynamic-group ipv6-address-group <name>
|
||||
|
||||
Add description to firewall groups:
|
||||
|
||||
.. cfgcmd:: set firewall group dynamic-group address-group <name>
|
||||
description <text>
|
||||
.. cfgcmd:: set firewall group dynamic-group ipv6-address-group <name>
|
||||
description <text>
|
||||
|
||||
Adding elements to Dynamic Firewall Groups
|
||||
------------------------------------------
|
||||
|
||||
Once dynamic firewall groups are defined, they should be used in firewall
|
||||
rules in order to dynamically add elements to it.
|
||||
|
||||
Commands used for this task are:
|
||||
|
||||
* Add destination IP address of the connection to a dynamic address group:
|
||||
|
||||
.. cfgcmd:: set firewall ipv4 [forward | input | output] filter rule
|
||||
<1-999999> add-address-to-group destination-address address-group <name>
|
||||
.. cfgcmd:: set firewall ipv4 name <name> rule <1-999999> add-address-to-group
|
||||
destination-address address-group <name>
|
||||
.. cfgcmd:: set firewall ipv6 [forward | input | output] filter rule
|
||||
<1-999999> add-address-to-group destination-address address-group <name>
|
||||
.. cfgcmd:: set firewall ipv6 name <name> rule <1-999999> add-address-to-group
|
||||
destination-address address-group <name>
|
||||
|
||||
* Add source IP address of the connection to a dynamic address group:
|
||||
|
||||
.. cfgcmd:: set firewall ipv4 [forward | input | output] filter rule
|
||||
<1-999999> add-address-to-group source-address address-group <name>
|
||||
.. cfgcmd:: set firewall ipv4 name <name> rule <1-999999> add-address-to-group
|
||||
source-address address-group <name>
|
||||
.. cfgcmd:: set firewall ipv6 [forward | input | output] filter rule
|
||||
<1-999999> add-address-to-group source-address address-group <name>
|
||||
.. cfgcmd:: set firewall ipv6 name <name> rule <1-999999> add-address-to-group
|
||||
source-address address-group <name>
|
||||
|
||||
Also, specific timeout can be defined per rule. In case rule gets a hit,
|
||||
source or destinatination address will be added to the group, and this
|
||||
element will remain in the group until timeout expires. If no timeout
|
||||
is defined, then the element will remain in the group until next reboot,
|
||||
or until a new commit that changes firewall configuration is done.
|
||||
|
||||
.. cfgcmd:: set firewall ipv4 [forward | input | output] filter rule
|
||||
<1-999999> add-address-to-group [destination-address | source-address]
|
||||
timeout <timeout>
|
||||
.. cfgcmd:: set firewall ipv4 name <name> rule <1-999999> add-address-to-group
|
||||
[destination-address | source-address] timeout <timeout>
|
||||
.. cfgcmd:: set firewall ipv6 [forward | input | output] filter rule
|
||||
<1-999999> add-address-to-group [destination-address | source-address]
|
||||
timeout <timeout>
|
||||
.. cfgcmd:: set firewall ipv6 name <name> rule <1-999999> add-address-to-group
|
||||
[destination-address | source-address] timeout <timeout>
|
||||
|
||||
Timeout can be defined using seconds, minutes, hours or days:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall ipv6 name FOO rule 10 add-address-to-group source-address timeout
|
||||
Possible completions:
|
||||
<number>s Timeout value in seconds
|
||||
<number>m Timeout value in minutes
|
||||
<number>h Timeout value in hours
|
||||
<number>d Timeout value in days
|
||||
|
||||
Using Dynamic Firewall Groups
|
||||
-----------------------------
|
||||
|
||||
As any other firewall group, dynamic firewall groups can be used in firewall
|
||||
rules as matching options. For example:
|
||||
|
||||
.. code-block:: none
|
||||
set firewall ipv4 input filter rule 10 source group dynamic-address-group FOO
|
||||
set firewall ipv4 input filter rule 10 destination group dynamic-address-group BAR
|
||||
|
||||
********
|
||||
Examples
|
||||
********
|
||||
|
||||
General example
|
||||
===============
|
||||
|
||||
As said before, once firewall groups are created, they can be referenced
|
||||
either in firewall, nat, nat66 and/or policy-route rules.
|
||||
|
||||
Here is an example were multiple groups are created:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall group address-group SERVERS address 198.51.100.101
|
||||
set firewall group address-group SERVERS address 198.51.100.102
|
||||
set firewall group network-group TRUSTEDv4 network 192.0.2.0/30
|
||||
set firewall group network-group TRUSTEDv4 network 203.0.113.128/25
|
||||
set firewall group ipv6-network-group TRUSTEDv6 network 2001:db8::/64
|
||||
set firewall group interface-group LAN interface eth2.2001
|
||||
set firewall group interface-group LAN interface bon0
|
||||
set firewall group port-group PORT-SERVERS port http
|
||||
set firewall group port-group PORT-SERVERS port 443
|
||||
set firewall group port-group PORT-SERVERS port 5000-5010
|
||||
|
||||
And next, some configuration example where groups are used:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall ipv4 output filter rule 10 action accept
|
||||
set firewall ipv4 output filter rule 10 outbound-interface group !LAN
|
||||
set firewall ipv4 forward filter rule 20 action accept
|
||||
set firewall ipv4 forward filter rule 20 source group network-group TRUSTEDv4
|
||||
set firewall ipv6 input filter rule 10 action accept
|
||||
set firewall ipv6 input filter rule 10 source group network-group TRUSTEDv6
|
||||
set nat destination rule 101 inbound-interface group LAN
|
||||
set nat destination rule 101 destination group address-group SERVERS
|
||||
set nat destination rule 101 protocol tcp
|
||||
set nat destination rule 101 destination group port-group PORT-SERVERS
|
||||
set nat destination rule 101 translation address 203.0.113.250
|
||||
set policy route PBR rule 201 destination group port-group PORT-SERVERS
|
||||
set policy route PBR rule 201 protocol tcp
|
||||
set policy route PBR rule 201 set table 15
|
||||
|
||||
Port knocking example
|
||||
=====================
|
||||
|
||||
Using dynamic firewall groups, we can secure access to the router, or any other
|
||||
device if needed, by using the technique of port knocking.
|
||||
|
||||
A 4 step port knocking example is shown next:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set firewall global-options state-policy established action 'accept'
|
||||
set firewall global-options state-policy invalid action 'drop'
|
||||
set firewall global-options state-policy related action 'accept'
|
||||
set firewall group dynamic-group address-group ALLOWED
|
||||
set firewall group dynamic-group address-group PN_01
|
||||
set firewall group dynamic-group address-group PN_02
|
||||
set firewall ipv4 input filter default-action 'drop'
|
||||
set firewall ipv4 input filter rule 5 action 'accept'
|
||||
set firewall ipv4 input filter rule 5 protocol 'icmp'
|
||||
set firewall ipv4 input filter rule 10 action 'drop'
|
||||
set firewall ipv4 input filter rule 10 add-address-to-group source-address address-group 'PN_01'
|
||||
set firewall ipv4 input filter rule 10 add-address-to-group source-address timeout '2m'
|
||||
set firewall ipv4 input filter rule 10 description 'Port_nock 01'
|
||||
set firewall ipv4 input filter rule 10 destination port '9990'
|
||||
set firewall ipv4 input filter rule 10 protocol 'tcp'
|
||||
set firewall ipv4 input filter rule 20 action 'drop'
|
||||
set firewall ipv4 input filter rule 20 add-address-to-group source-address address-group 'PN_02'
|
||||
set firewall ipv4 input filter rule 20 add-address-to-group source-address timeout '3m'
|
||||
set firewall ipv4 input filter rule 20 description 'Port_nock 02'
|
||||
set firewall ipv4 input filter rule 20 destination port '9991'
|
||||
set firewall ipv4 input filter rule 20 protocol 'tcp'
|
||||
set firewall ipv4 input filter rule 20 source group dynamic-address-group 'PN_01'
|
||||
set firewall ipv4 input filter rule 30 action 'drop'
|
||||
set firewall ipv4 input filter rule 30 add-address-to-group source-address address-group 'ALLOWED'
|
||||
set firewall ipv4 input filter rule 30 add-address-to-group source-address timeout '2h'
|
||||
set firewall ipv4 input filter rule 30 description 'Port_nock 03'
|
||||
set firewall ipv4 input filter rule 30 destination port '9992'
|
||||
set firewall ipv4 input filter rule 30 protocol 'tcp'
|
||||
set firewall ipv4 input filter rule 30 source group dynamic-address-group 'PN_02'
|
||||
set firewall ipv4 input filter rule 99 action 'accept'
|
||||
set firewall ipv4 input filter rule 99 description 'Port_nock 04 - Allow ssh'
|
||||
set firewall ipv4 input filter rule 99 destination port '22'
|
||||
set firewall ipv4 input filter rule 99 protocol 'tcp'
|
||||
set firewall ipv4 input filter rule 99 source group dynamic-address-group 'ALLOWED'
|
||||
|
||||
Before testing, we can check members of firewall groups:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos# run show firewall group
|
||||
Firewall Groups
|
||||
|
||||
Name Type References Members Timeout Expires
|
||||
------- ---------------------- -------------------- ------------- --------- ---------
|
||||
ALLOWED address_group(dynamic) ipv4-input-filter-30 N/D N/D N/D
|
||||
PN_01 address_group(dynamic) ipv4-input-filter-10 N/D N/D N/D
|
||||
PN_02 address_group(dynamic) ipv4-input-filter-20 N/D N/D N/D
|
||||
[edit]
|
||||
vyos@vyos#
|
||||
|
||||
With this configuration, in order to get ssh access to the router, user
|
||||
needs to:
|
||||
|
||||
1. Generate a new TCP connection with destination port 9990. As shown next,
|
||||
a new entry was added to dynamic firewall group **PN_01**
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos# run show firewall group
|
||||
Firewall Groups
|
||||
|
||||
Name Type References Members Timeout Expires
|
||||
------- ---------------------- -------------------- ------------- --------- ---------
|
||||
ALLOWED address_group(dynamic) ipv4-input-filter-30 N/D N/D N/D
|
||||
PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.89.31 120 119
|
||||
PN_02 address_group(dynamic) ipv4-input-filter-20 N/D N/D N/D
|
||||
[edit]
|
||||
vyos@vyos#
|
||||
|
||||
2. Generate a new TCP connection with destination port 9991. As shown next,
|
||||
a new entry was added to dynamic firewall group **PN_02**
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos# run show firewall group
|
||||
Firewall Groups
|
||||
|
||||
Name Type References Members Timeout Expires
|
||||
------- ---------------------- -------------------- ------------- --------- ---------
|
||||
ALLOWED address_group(dynamic) ipv4-input-filter-30 N/D N/D N/D
|
||||
PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.89.31 120 106
|
||||
PN_02 address_group(dynamic) ipv4-input-filter-20 192.168.89.31 180 179
|
||||
[edit]
|
||||
vyos@vyos#
|
||||
|
||||
3. Generate a new TCP connection with destination port 9992. As shown next,
|
||||
a new entry was added to dynamic firewall group **ALLOWED**
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos# run show firewall group
|
||||
Firewall Groups
|
||||
|
||||
Name Type References Members Timeout Expires
|
||||
------- ---------------------- -------------------- ------------- --------- ---------
|
||||
ALLOWED address_group(dynamic) ipv4-input-filter-30 192.168.89.31 7200 7199
|
||||
PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.89.31 120 89
|
||||
PN_02 address_group(dynamic) ipv4-input-filter-20 192.168.89.31 180 170
|
||||
[edit]
|
||||
vyos@vyos#
|
||||
|
||||
4. Now user can connect through ssh to the router (assuming ssh is configured).
|
||||
|
||||
**************
|
||||
Operation-mode
|
||||
**************
|
||||
|
||||
.. opcmd:: show firewall group
|
||||
.. opcmd:: show firewall group <name>
|
||||
|
||||
Overview of defined groups. You see the firewall group name, type,
|
||||
references (where the group is used), members, timeout and expiration (last
|
||||
two only present in dynamic firewall groups).
|
||||
|
||||
Here is an example of such command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos:~$ show firewall group
|
||||
Firewall Groups
|
||||
|
||||
Name Type References Members Timeout Expires
|
||||
------------ ---------------------- ---------------------- ---------------- --------- ---------
|
||||
SERVERS address_group nat-destination-101 198.51.100.101
|
||||
198.51.100.102
|
||||
ALLOWED address_group(dynamic) ipv4-input-filter-30 192.168.77.39 7200 7174
|
||||
PN_01 address_group(dynamic) ipv4-input-filter-10 192.168.0.245 120 112
|
||||
192.168.77.39 120 85
|
||||
PN_02 address_group(dynamic) ipv4-input-filter-20 192.168.77.39 180 151
|
||||
LAN interface_group ipv4-output-filter-10 bon0
|
||||
nat-destination-101 eth2.2001
|
||||
TRUSTEDv6 ipv6_network_group ipv6-input-filter-10 2001:db8::/64
|
||||
TRUSTEDv4 network_group ipv4-forward-filter-20 192.0.2.0/30
|
||||
203.0.113.128/25
|
||||
PORT-SERVERS port_group route-PBR-201 443
|
||||
route-PBR-201 5000-5010
|
||||
nat-destination-101 http
|
||||
vyos@vyos:~$
|
||||
@ -1,24 +1,180 @@
|
||||
:lastproofread: 2023-11-23
|
||||
|
||||
########
|
||||
Firewall
|
||||
########
|
||||
|
||||
Starting from VyOS 1.4-rolling-202308040557, a new firewall structure
|
||||
can be found on all vyos installations. Documentation for most new firewall
|
||||
cli can be found here:
|
||||
As VyOS is based on Linux it leverages its firewall. The Netfilter project
|
||||
created iptables and its successor nftables for the Linux kernel to
|
||||
work directly on packet data flows. This now extends the concept of
|
||||
zone-based security to allow for manipulating the data at multiple stages once
|
||||
accepted by the network interface and the driver before being handed off to
|
||||
the destination (e.g., a web server OR another device).
|
||||
|
||||
A simplified traffic flow diagram, based on Netfilter packet flow, is shown
|
||||
next, in order to have a full view and understanding of how packets are
|
||||
processed, and what possible paths traffic can take.
|
||||
|
||||
.. figure:: /_static/images/firewall-gral-packet-flow.png
|
||||
|
||||
The main points regarding this packet flow and terminology used in VyOS
|
||||
firewall are covered below:
|
||||
|
||||
* **Bridge Port?**: choose appropriate path based on whether interface
|
||||
where the packet was received is part of a bridge, or not.
|
||||
|
||||
If the interface where the packet was received isn't part of a bridge, then
|
||||
packetis processed at the **IP Layer**:
|
||||
|
||||
* **Prerouting**: several actions can be done in this stage, and currently
|
||||
these actions are defined in different parts in VyOS configuration. Order
|
||||
is important, and all these actions are performed before any actions
|
||||
defined under ``firewall`` section. Relevant configuration that acts in
|
||||
this stage are:
|
||||
|
||||
* **Conntrack Ignore**: rules defined under ``set system conntrack ignore
|
||||
[ipv4 | ipv6] ...``.
|
||||
|
||||
* **Policy Route**: rules defined under ``set policy [route | route6]
|
||||
...``.
|
||||
|
||||
* **Destination NAT**: rules defined under ``set [nat | nat66]
|
||||
destination...``.
|
||||
|
||||
* **Destination is the router?**: choose appropriate path based on
|
||||
destination IP address. Transit forward continues to **forward**,
|
||||
while traffic that destination IP address is configured on the router
|
||||
continues to **input**.
|
||||
|
||||
* **Input**: stage where traffic destined for the router itself can be
|
||||
filtered and controlled. This is where all rules for securing the router
|
||||
should take place. This includes ipv4 and ipv6 filtering rules, defined
|
||||
in:
|
||||
|
||||
* ``set firewall ipv4 input filter ...``.
|
||||
|
||||
* ``set firewall ipv6 input filter ...``.
|
||||
|
||||
* **Forward**: stage where transit traffic can be filtered and controlled.
|
||||
This includes ipv4 and ipv6 filtering rules, defined in:
|
||||
|
||||
* ``set firewall ipv4 forward filter ...``.
|
||||
|
||||
* ``set firewall ipv6 forward filter ...``.
|
||||
|
||||
* **Output**: stage where traffic that originates from the router itself
|
||||
can be filtered and controlled. Bear in mind that this traffic can be a
|
||||
new connection originated by a internal process running on VyOS router,
|
||||
such as NTP, or a response to traffic received externaly through
|
||||
**input** (for example response to an ssh login attempt to the router).
|
||||
This includes ipv4 and ipv6 filtering rules, defined in:
|
||||
|
||||
* ``set firewall ipv4 output filter ...``.
|
||||
|
||||
* ``set firewall ipv6 output filter ...``.
|
||||
|
||||
* **Postrouting**: as in **Prerouting**, several actions defined in
|
||||
different parts of VyOS configuration are performed in this
|
||||
stage. This includes:
|
||||
|
||||
* **Source NAT**: rules defined under ``set [nat | nat66]
|
||||
destination...``.
|
||||
|
||||
If the interface where the packet was received is part of a bridge, then
|
||||
the packet is processed at the **Bridge Layer**, which contains a basic setup for
|
||||
bridge filtering:
|
||||
|
||||
* **Forward (Bridge)**: stage where traffic that is trespasing through the
|
||||
bridge is filtered and controlled:
|
||||
|
||||
* ``set firewall bridge forward filter ...``.
|
||||
|
||||
The main structure of the VyOS firewall CLI is shown next:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
- set firewall
|
||||
* bridge
|
||||
- forward
|
||||
+ filter
|
||||
* flowtable
|
||||
- custom_flow_table
|
||||
+ ...
|
||||
* global-options
|
||||
+ all-ping
|
||||
+ broadcast-ping
|
||||
+ ...
|
||||
* group
|
||||
- address-group
|
||||
- ipv6-address-group
|
||||
- network-group
|
||||
- ipv6-network-group
|
||||
- interface-group
|
||||
- mac-group
|
||||
- port-group
|
||||
- domain-group
|
||||
* ipv4
|
||||
- forward
|
||||
+ filter
|
||||
- input
|
||||
+ filter
|
||||
- output
|
||||
+ filter
|
||||
- name
|
||||
+ custom_name
|
||||
* ipv6
|
||||
- forward
|
||||
+ filter
|
||||
- input
|
||||
+ filter
|
||||
- output
|
||||
+ filter
|
||||
- ipv6-name
|
||||
+ custom_name
|
||||
* zone
|
||||
- custom_zone_name
|
||||
+ ...
|
||||
|
||||
Please, refer to appropriate section for more information about firewall
|
||||
configuration:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:includehidden:
|
||||
|
||||
general
|
||||
global-options
|
||||
groups
|
||||
bridge
|
||||
ipv4
|
||||
ipv6
|
||||
flowtables
|
||||
|
||||
Also, for those who haven't updated to newer version, legacy documentation is
|
||||
still present and valid for all sagitta version prior to VyOS
|
||||
1.4-rolling-202308040557:
|
||||
.. note:: **For more information**
|
||||
of Netfilter hooks and Linux networking packet flows can be
|
||||
found in `Netfilter-Hooks
|
||||
<https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks>`_
|
||||
|
||||
|
||||
Zone-based firewall
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:includehidden:
|
||||
|
||||
general-legacy
|
||||
zone
|
||||
|
||||
With zone-based firewalls a new concept was implemented, in addition to the
|
||||
standard in and out traffic flows, a local flow was added. This local was for
|
||||
traffic originating and destined to the router itself. Which means additional
|
||||
rules were required to secure the firewall itself from the network, in
|
||||
addition to the existing inbound and outbound rules from the traditional
|
||||
concept above.
|
||||
|
||||
To configure VyOS with the
|
||||
:doc:`zone-based firewall configuration </configuration/firewall/zone>`
|
||||
|
||||
As the example image below shows, the device now needs rules to allow/block
|
||||
traffic to or from the services running on the device that have open
|
||||
connections on that interface.
|
||||
|
||||
.. figure:: /_static/images/firewall-zonebased.png
|
||||
|
||||
1229
docs/configuration/firewall/ipv4.rst
Normal file
1225
docs/configuration/firewall/ipv6.rst
Normal file
@ -1,4 +1,4 @@
|
||||
:lastproofread: 2022-09-14
|
||||
:lastproofread: 2023-11-01
|
||||
|
||||
.. _firewall-zone:
|
||||
|
||||
@ -6,20 +6,39 @@
|
||||
Zone Based Firewall
|
||||
###################
|
||||
|
||||
********
|
||||
Overview
|
||||
********
|
||||
|
||||
.. note:: Starting from VyOS 1.4-rolling-202308040557, a new firewall
|
||||
structure can be found on all vyos instalations, and zone based firewall is
|
||||
no longer supported. Documentation for most of the new firewall CLI can be
|
||||
structure can be found on all vyos instalations. Zone based firewall was
|
||||
removed in that version, but re introduced in VyOS 1.4 and 1.5. All
|
||||
versions built after 2023-10-22 has this feature.
|
||||
Documentation for most of the new firewall CLI can be
|
||||
found in the `firewall
|
||||
<https://docs.vyos.io/en/latest/configuration/firewall/general.html>`_
|
||||
chapter. The legacy firewall is still available for versions before
|
||||
1.4-rolling-202308040557 and can be found in the :ref:`firewall-legacy`
|
||||
chapter. The examples in this section use the legacy firewall configuration
|
||||
commands, since this feature has been removed in earlier releases.
|
||||
1.4-rolling-202308040557 and can be found in the
|
||||
:doc:`legacy firewall configuration </configuration/firewall/general-legacy>`
|
||||
chapter.
|
||||
|
||||
.. note:: For latest releases, refer the `firewall
|
||||
<https://docs.vyos.io/en/latest/configuration/firewall/general.html#interface-groups>`_
|
||||
main page to configure zone based rules. New syntax was introduced here
|
||||
:vytask:`T5160`
|
||||
In this section there's useful information of all firewall configuration that
|
||||
is needed for zone-based firewall.
|
||||
Configuration commands covered in this section:
|
||||
|
||||
.. cfgcmd:: set firewall zone ...
|
||||
|
||||
From main structure defined in
|
||||
:doc:`Firewall Overview</configuration/firewall/index>`
|
||||
in this section you can find detailed information only for the next part
|
||||
of the general structure:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
- set firewall
|
||||
* zone
|
||||
- custom_zone_name
|
||||
+ ...
|
||||
|
||||
In zone-based policy, interfaces are assigned to zones, and inspection policy
|
||||
is applied to traffic moving between the zones and acted on according to
|
||||
@ -104,3 +123,41 @@ written from the perspective of: *Source Zone*-to->*Destination Zone*
|
||||
set firewall zone DMZ from LAN firewall name LANv4-to-DMZv4
|
||||
set firewall zone LAN from DMZ firewall name DMZv4-to-LANv4
|
||||
|
||||
**************
|
||||
Operation-mode
|
||||
**************
|
||||
|
||||
.. opcmd:: show firewall zone-policy
|
||||
|
||||
This will show you a basic summary of zones configuration.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos:~$ show firewall zone-policy
|
||||
Zone Interfaces From Zone Firewall IPv4 Firewall IPv6
|
||||
------ ------------ ----------- --------------- ---------------
|
||||
LAN eth1 WAN WAN_to_LAN
|
||||
eth2
|
||||
LOCAL LOCAL LAN LAN_to_LOCAL
|
||||
WAN WAN_to_LOCAL WAN_to_LOCAL_v6
|
||||
WAN eth3 LAN LAN_to_WAN
|
||||
eth0 LOCAL LOCAL_to_WAN
|
||||
vyos@vyos:~$
|
||||
|
||||
.. opcmd:: show firewall zone-policy zone <zone>
|
||||
|
||||
This will show you a basic summary of a particular zone.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos:~$ show firewall zone-policy zone WAN
|
||||
Zone Interfaces From Zone Firewall IPv4 Firewall IPv6
|
||||
------ ------------ ----------- --------------- ---------------
|
||||
WAN eth3 LAN LAN_to_WAN
|
||||
eth0 LOCAL LOCAL_to_WAN
|
||||
vyos@vyos:~$ show firewall zone-policy zone LOCAL
|
||||
Zone Interfaces From Zone Firewall IPv4 Firewall IPv6
|
||||
------ ------------ ----------- --------------- ---------------
|
||||
LOCAL LOCAL LAN LAN_to_LOCAL
|
||||
WAN WAN_to_LOCAL WAN_to_LOCAL_v6
|
||||
vyos@vyos:~$
|
||||
|
||||
@ -318,6 +318,16 @@ times:
|
||||
set high-availability vrrp group Foo health-check interval 60
|
||||
set high-availability vrrp group Foo health-check failure-count 3
|
||||
|
||||
When the vrrp group is a member of the sync group will use only
|
||||
the sync group health check script.
|
||||
This example shows how to configure it for the sync group:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set high-availability vrrp sync-group Bar health-check script /config/scripts/vrrp-check.sh
|
||||
set high-availability vrrp sync-group Bar health-check interval 60
|
||||
set high-availability vrrp sync-group Bar health-check failure-count 3
|
||||
|
||||
Transition scripts
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@ -156,6 +156,11 @@ Bond options
|
||||
|
||||
The default value is slow.
|
||||
|
||||
.. cfgcmd:: set interfaces bonding <interface> system-mac <mac address>
|
||||
|
||||
This option allow to specifies the 802.3ad system MAC address.You can set a
|
||||
random mac-address that can be used for these LACPDU exchanges.
|
||||
|
||||
.. cfgcmd:: set interfaces bonding <interface> hash-policy <policy>
|
||||
|
||||
* **layer2** - Uses XOR of hardware MAC addresses and packet type ID field
|
||||
@ -286,6 +291,54 @@ Port Mirror (SPAN)
|
||||
:var1: bond1
|
||||
:var2: eth3
|
||||
|
||||
EVPN Multihoming
|
||||
----------------
|
||||
|
||||
All-Active Multihoming is used for redundancy and load sharing. Servers are
|
||||
attached to two or more PEs and the links are bonded (link-aggregation).
|
||||
This group of server links is referred to as an :abbr:`ES (Ethernet Segment)`.
|
||||
|
||||
An Ethernet Segment can be configured by specifying a system-MAC and a local
|
||||
discriminator or a complete ESINAME against the bond interface on the PE.
|
||||
|
||||
.. cfgcmd:: set interfaces bonding <interface> evpn es-id <<1-16777215|10-byte ID>
|
||||
.. cfgcmd:: set interfaces bonding <interface> evpn es-sys-mac <xx:xx:xx:xx:xx:xx>
|
||||
|
||||
The sys-mac and local discriminator are used for generating a 10-byte, Type-3
|
||||
Ethernet Segment ID. ESINAME is a 10-byte, Type-0 Ethernet Segment ID -
|
||||
"00:AA:BB:CC:DD:EE:FF:GG:HH:II".
|
||||
|
||||
Type-1 (EAD-per-ES and EAD-per-EVI) routes are used to advertise the locally
|
||||
attached ESs and to learn off remote ESs in the network. Local Type-2/MAC-IP
|
||||
routes are also advertised with a destination ESI allowing for MAC-IP syncing
|
||||
between Ethernet Segment peers. Reference: RFC 7432, RFC 8365
|
||||
|
||||
EVPN-MH is intended as a replacement for MLAG or Anycast VTEPs. In multihoming
|
||||
each PE has an unique VTEP address which requires the introduction of a new
|
||||
dataplane construct, MAC-ECMP. Here a MAC/FDB entry can point to a list of
|
||||
remote PEs/VTEPs.
|
||||
|
||||
.. cfgcmd:: set interfaces bonding <interface> evpn es-df-pref <1-65535>
|
||||
|
||||
Type-4 (ESR) routes are used for Designated Forwarder (DF) election.
|
||||
DFs forward BUM traffic received via the overlay network. This
|
||||
implementation uses a preference based DF election specified by
|
||||
draft-ietf-bess-evpn-pref-df.
|
||||
|
||||
The DF preference is configurable per-ES.
|
||||
|
||||
BUM traffic is rxed via the overlay by all PEs attached to a server but
|
||||
only the DF can forward the de-capsulated traffic to the access port.
|
||||
To accommodate that non-DF filters are installed in the dataplane to drop
|
||||
the traffic.
|
||||
|
||||
Similarly traffic received from ES peers via the overlay cannot be forwarded
|
||||
to the server. This is split-horizon-filtering with local bias.
|
||||
|
||||
.. cmdinclude:: /_include/interface-evpn-uplink.txt
|
||||
:var0: bonding
|
||||
:var1: bond0
|
||||
|
||||
*******
|
||||
Example
|
||||
*******
|
||||
@ -590,4 +643,3 @@ Operation
|
||||
Partner Churn State: churned
|
||||
Actor Churned Count: 1
|
||||
Partner Churned Count: 1
|
||||
|
||||
|
||||
@ -127,15 +127,24 @@ Enable VLAN-Aware Bridge
|
||||
|
||||
.. cfgcmd:: set interfaces bridge <interface> enable-vlan
|
||||
|
||||
To activate the VLAN aware bridge, you must activate this setting to use VLAN
|
||||
To activate the VLAN aware bridge, you must activate this setting to use VLAN
|
||||
settings for the bridge
|
||||
|
||||
.. cfgcmd:: set interfaces bridge <interface> protocol <802.1ad|802.1q>
|
||||
|
||||
Define used ethertype of bridge interface.
|
||||
|
||||
Ethertype ``0x8100`` is used for ``802.1q`` and ethertype ``0x88a8`` is used
|
||||
for ``802.1ad``.
|
||||
|
||||
The default is ``802.1q``.
|
||||
|
||||
VLAN Options
|
||||
------------
|
||||
|
||||
.. note:: It is not valid to use the `vif 1` option for VLAN aware bridges
|
||||
because VLAN aware bridges assume that all unlabeled packets belong to
|
||||
the default VLAN 1 member and that the VLAN ID of the bridge's parent
|
||||
because VLAN aware bridges assume that all unlabeled packets belong to
|
||||
the default VLAN 1 member and that the VLAN ID of the bridge's parent
|
||||
interface is always 1
|
||||
|
||||
.. cmdinclude:: /_include/interface-vlan-8021q.txt
|
||||
@ -149,9 +158,9 @@ VLAN Options
|
||||
VLAN tag enters the port, the data packet will be forced to add a tag of a
|
||||
specific vlan id. When the vlan id flag flows out, the tag of the vlan id
|
||||
will be stripped
|
||||
|
||||
|
||||
Example: Set `eth0` member port to be native VLAN 2
|
||||
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set interfaces bridge br1 member interface eth0 native-vlan 2
|
||||
@ -162,17 +171,17 @@ VLAN Options
|
||||
Allows specific VLAN IDs to pass through the bridge member interface. This
|
||||
can either be an individual VLAN id or a range of VLAN ids delimited by a
|
||||
hyphen.
|
||||
|
||||
|
||||
Example: Set `eth0` member port to be allowed VLAN 4
|
||||
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
||||
set interfaces bridge br1 member interface eth0 allowed-vlan 4
|
||||
|
||||
|
||||
Example: Set `eth0` member port to be allowed VLAN 6-8
|
||||
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
||||
set interfaces bridge br1 member interface eth0 allowed-vlan 6-8
|
||||
|
||||
Port Mirror (SPAN)
|
||||
@ -265,17 +274,17 @@ This results in the active configuration:
|
||||
Using the operation mode command to view Bridge Information
|
||||
===========================================================
|
||||
|
||||
.. opcmd:: show bridge
|
||||
.. opcmd:: show bridge
|
||||
|
||||
The `show bridge` operational command can be used to display
|
||||
configured bridges:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos:~$ show bridge
|
||||
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
|
||||
priority 32 cost 100
|
||||
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
|
||||
vyos@vyos:~$ show bridge
|
||||
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
|
||||
priority 32 cost 100
|
||||
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding
|
||||
priority 32 cost 100
|
||||
|
||||
.. opcmd:: show bridge <name> fdb
|
||||
@ -304,11 +313,11 @@ Using the operation mode command to view Bridge Information
|
||||
33:33:00:00:00:6a dev br0 self permanent
|
||||
01:00:5e:00:00:01 dev br0 self permanent
|
||||
33:33:ff:00:00:00 dev br0 self permanent
|
||||
|
||||
|
||||
.. opcmd:: show bridge <name> mdb
|
||||
|
||||
Show bridge `<name>` mdb displays the current multicast group membership
|
||||
table.The table is populated by IGMP and MLD snooping in the bridge driver
|
||||
Show bridge `<name>` mdb displays the current multicast group membership
|
||||
table.The table is populated by IGMP and MLD snooping in the bridge driver
|
||||
automatically.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
@ -61,6 +61,22 @@ Offloading
|
||||
|
||||
Enable different types of hardware offloading on the given NIC.
|
||||
|
||||
:abbr:`LRO (Large Receive Offload)` is a technique designed to boost the
|
||||
efficiency of how your computer's network interface card (NIC) processes
|
||||
incoming network traffic. Typically, network data arrives in smaller chunks
|
||||
called packets. Processing each packet individually consumes CPU (central
|
||||
processing unit) resources. Lots of small packets can lead to a performance
|
||||
bottleneck. Instead of handing the CPU each packet as it comes in, LRO
|
||||
instructs the NIC to combine multiple incoming packets into a single, larger
|
||||
packet. This larger packet is then passed to the CPU for processing.
|
||||
|
||||
.. note:: Under some circumstances, LRO is known to modify the packet headers
|
||||
of forwarded traffic, which breaks the end-to-end principle of computer
|
||||
networking. LRO is also only able to offload TCP segments encapsulated in
|
||||
IPv4 packets. Due to these limitations, it is recommended to use GRO
|
||||
(Generic Receive Offload) where possible. More information on the
|
||||
limitations of LRO can be found here: https://lwn.net/Articles/358910/
|
||||
|
||||
:abbr:`GSO (Generic Segmentation Offload)` is a pure software offload that is
|
||||
meant to deal with cases where device drivers cannot perform the offloads
|
||||
described above. What occurs in GSO is that a given skbuff will have its data
|
||||
@ -87,13 +103,13 @@ Offloading
|
||||
placing the packet on the desired CPU's backlog queue and waking up the CPU
|
||||
for processing. RPS has some advantages over RSS:
|
||||
|
||||
- it can be used with any NIC,
|
||||
- software filters can easily be added to hash over new protocols,
|
||||
- it does not increase hardware device interrupt rate (although it does
|
||||
introduce inter-processor interrupts (IPIs)).
|
||||
- it can be used with any NIC
|
||||
- software filters can easily be added to hash over new protocols
|
||||
- it does not increase hardware device interrupt rate, although it does
|
||||
introduce inter-processor interrupts (IPIs)
|
||||
|
||||
.. note:: In order to use TSO/LRO with VMXNET3 adaters one must also enable
|
||||
the SG offloading option.
|
||||
.. note:: In order to use TSO/LRO with VMXNET3 adapters, the SG offloading
|
||||
option must also be enabled.
|
||||
|
||||
Authentication (EAPoL)
|
||||
----------------------
|
||||
@ -102,6 +118,14 @@ Authentication (EAPoL)
|
||||
:var0: ethernet
|
||||
:var1: eth0
|
||||
|
||||
EVPN Multihoming
|
||||
----------------
|
||||
|
||||
Uplink/Core tracking.
|
||||
|
||||
.. cmdinclude:: /_include/interface-evpn-uplink.txt
|
||||
:var0: ethernet
|
||||
:var1: eth0
|
||||
|
||||
VLAN
|
||||
====
|
||||
@ -273,4 +297,3 @@ Operation
|
||||
Date code : 0506xx
|
||||
|
||||
.. stop_vyoslinter
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ services on your local machine.
|
||||
you need multiple interfaces, please use the :ref:`dummy-interface`
|
||||
interface type.
|
||||
|
||||
.. hint:: A lookback interface is always up, thus it could be used for
|
||||
.. hint:: A loopback interface is always up, thus it could be used for
|
||||
management traffic or as source/destination for and :abbr:`IGP (Interior
|
||||
Gateway Protocol)` like :ref:`routing-bgp` so your internal BGP link is not
|
||||
dependent on physical link states and multiple routes can be chosen to the
|
||||
|
||||
@ -71,7 +71,7 @@ In both cases, we will use the following settings:
|
||||
dynamic IP for our remote router.
|
||||
|
||||
Setting up certificates
|
||||
-----------------------
|
||||
=======================
|
||||
|
||||
Setting up a full-blown PKI with a CA certificate would arguably defeat the purpose
|
||||
of site-to-site OpenVPN, since its main goal is supposed to be configuration simplicity,
|
||||
@ -129,7 +129,7 @@ Note: certificate names don't matter, we use 'openvpn-local' and 'openvpn-remote
|
||||
Repeat the procedure on the other router.
|
||||
|
||||
Setting up OpenVPN
|
||||
------------------
|
||||
==================
|
||||
|
||||
Local Configuration:
|
||||
|
||||
@ -148,6 +148,7 @@ Local Configuration:
|
||||
set interfaces openvpn vtun1 tls certificate 'openvpn-local' # The self-signed certificate
|
||||
set interfaces openvpn vtun1 tls peer-fingerprint <remote cert fingerprint> # The output of 'run show pki certificate <name> fingerprint sha256
|
||||
on the remote rout
|
||||
|
||||
Remote Configuration:
|
||||
|
||||
.. code-block:: none
|
||||
@ -163,8 +164,9 @@ Remote Configuration:
|
||||
set interfaces openvpn vtun1 tls certificate 'openvpn-remote' # The self-signed certificate
|
||||
set interfaces openvpn vtun1 tls peer-fingerprint <local cert fingerprint> # The output of 'run show pki certificate <name> fingerprint sha256
|
||||
on the local router
|
||||
|
||||
Pre-shared keys
|
||||
---------------
|
||||
===============
|
||||
|
||||
Until VyOS 1.4, the only option for site-to-site OpenVPN without PKI was to use pre-shared keys.
|
||||
That option is still available but it is deprecated and will be removed in the future.
|
||||
@ -200,6 +202,7 @@ Then you need to install the key on the remote router:
|
||||
Then you need to set the key in your OpenVPN interface settings:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set interfaces openvpn vtun1 shared-secret-key s2s
|
||||
|
||||
Firewall Exceptions
|
||||
@ -433,6 +436,7 @@ Branch 1's router might have the following lines:
|
||||
set interfaces openvpn vtun10 tls ca-cert ca-1
|
||||
set interfaces openvpn vtun10 tls certificate branch-1
|
||||
|
||||
|
||||
Client Authentication
|
||||
=====================
|
||||
|
||||
@ -544,7 +548,7 @@ example:
|
||||
openvpn-option "--plugin /usr/lib/openvpn/openvpn-auth-ldap.so /config/auth/ldap-auth.config"
|
||||
openvpn-option "--push redirect-gateway"
|
||||
openvpn-option --duplicate-cn
|
||||
openvpn-option --client-cert-not-required
|
||||
openvpn-option "--verify-client-cert none"
|
||||
openvpn-option --comp-lzo
|
||||
openvpn-option --persist-key
|
||||
openvpn-option --persist-tun
|
||||
@ -649,6 +653,88 @@ Will add ``push "keepalive 1 10"`` to the generated OpenVPN config file.
|
||||
quotes. This is done through a hack on our config generator. You can pass
|
||||
quotes using the ``"`` statement.
|
||||
|
||||
***************************
|
||||
Multi-factor Authentication
|
||||
***************************
|
||||
|
||||
VyOS supports multi-factor authentication (MFA) or two-factor authentication
|
||||
using Time-based One-Time Password (TOTP). Compatible with Google Authenticator
|
||||
software token, other software tokens.
|
||||
|
||||
MFA TOTP options
|
||||
================
|
||||
|
||||
.. cfgcmd:: set interfaces openvpn <interface> server mfa totp challenge <enable | disable>
|
||||
|
||||
If set to enable, openvpn-otp will expect password as result of challenge/
|
||||
response protocol.
|
||||
|
||||
.. cfgcmd:: set interfaces openvpn <interface> server mfa totp digits <1-65535>
|
||||
|
||||
Configure number of digits to use for totp hash (default: 6)
|
||||
|
||||
.. cfgcmd:: set interfaces openvpn <interface> server mfa totp drift <1-65535>
|
||||
|
||||
Configure time drift in seconds (default: 0)
|
||||
|
||||
.. cfgcmd:: set interfaces openvpn <interface> server mfa totp slop <1-65535>
|
||||
|
||||
Configure maximum allowed clock slop in seconds (default: 180)
|
||||
|
||||
.. cfgcmd:: set interfaces openvpn <interface> server mfa totp step <1-65535>
|
||||
|
||||
Configure step value for totp in seconds (default: 30)
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
set interfaces openvpn vtun20 encryption cipher 'aes256'
|
||||
set interfaces openvpn vtun20 hash 'sha512'
|
||||
set interfaces openvpn vtun20 mode 'server'
|
||||
set interfaces openvpn vtun20 persistent-tunnel
|
||||
set interfaces openvpn vtun20 server client user1
|
||||
set interfaces openvpn vtun20 server mfa totp challenge 'disable'
|
||||
set interfaces openvpn vtun20 server subnet '10.10.2.0/24'
|
||||
set interfaces openvpn vtun20 server topology 'subnet'
|
||||
set interfaces openvpn vtun20 tls ca-certificate 'openvpn_vtun20'
|
||||
set interfaces openvpn vtun20 tls certificate 'openvpn_vtun20'
|
||||
set interfaces openvpn vtun20 tls dh-params 'dh-pem'
|
||||
|
||||
For every client in the openvpn server configuration a totp secret is created.
|
||||
To display the authentication information, use the command:
|
||||
|
||||
.. cfgcmd:: show interfaces openvpn <interface> user <username> mfa <qrcode|secret|uri>
|
||||
|
||||
An example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
vyos@vyos:~$ sh interfaces openvpn vtun20 user user1 mfa qrcode
|
||||
█████████████████████████████████████
|
||||
█████████████████████████████████████
|
||||
████ ▄▄▄▄▄ █▀▄▀ ▀▀▄▀ ▀▀▄ █ ▄▄▄▄▄ ████
|
||||
████ █ █ █▀▀▄ █▀▀▀█▀██ █ █ █ ████
|
||||
████ █▄▄▄█ █▀█ ▄ █▀▀ █▄▄▄█ █▄▄▄█ ████
|
||||
████▄▄▄▄▄▄▄█▄█ █ █ ▀ █▄▀▄█▄▄▄▄▄▄▄████
|
||||
████▄▄ ▄ █▄▄ ▄▀▄█▄ ▄▀▄█ ▄▄▀ ▀▄█ ▀████
|
||||
████ ▀██▄▄▄█▄ ██ █▄▄▄▄ █▄▀█ █ █▀█████
|
||||
████ ▄█▀▀▄▄ ▄█▀ ▀▄ ▄▄▀▄█▀▀▀ ▄▄▀████
|
||||
████▄█ ▀▄▄▄▀ ▀ ▄█ ▄ █▄█▀ █▀ █▀█████
|
||||
████▀█▀ ▀ ▄█▀▄▀▀█▄██▄█▀▀ ▀ ▀ ▄█▀████
|
||||
████ ██▄▄▀▄▄█ ██ ▀█ ▄█ ▀▄█ █▀██▀████
|
||||
████▄███▄█▄█ ▀█▄ ██▄▄▄█▀ ▄▄▄ █ ▀ ████
|
||||
████ ▄▄▄▄▄ █▄█▀▄ ▀▄ ▀█▀ █▄█ ██▀█████
|
||||
████ █ █ █ ▄█▀█▀▀▄ ▄▀▀▄▄▄▄▄▄ ████
|
||||
████ █▄▄▄█ █ ▄ ▀ █▄▄▄██▄▀█▄▀▄█▄ █████
|
||||
████▄▄▄▄▄▄▄█▄██▄█▄▄▄▄▄█▄█▄█▄██▄██████
|
||||
█████████████████████████████████████
|
||||
█████████████████████████████████████
|
||||
|
||||
Use the QR code to add the user account in Google authenticator application and
|
||||
on client side, use the OTP number as password.
|
||||
|
||||
|
||||
**********************************
|
||||
OpenVPN Data Channel Offload (DCO)
|
||||
|
||||
@ -143,6 +143,19 @@ PPPoE options
|
||||
|
||||
set interfaces pppoe pppoe0 default-route-distance 220
|
||||
|
||||
.. cfgcmd:: set interfaces pppoe <interface> mru <mru>
|
||||
|
||||
Set the :abbr:`MRU (Maximum Receive Unit)` to `mru`. PPPd will ask the peer to
|
||||
send packets of no more than `mru` bytes. The value of `mru` must be between 128
|
||||
and 16384.
|
||||
|
||||
A value of 296 works well on very slow links (40 bytes for TCP/IP header + 256
|
||||
bytes of data).
|
||||
|
||||
The default is 1492.
|
||||
|
||||
.. note:: When using the IPv6 protocol, MRU must be at least 1280 bytes.
|
||||
|
||||
.. cfgcmd:: set interfaces pppoe <interface> idle-timeout <time>
|
||||
|
||||
Use this command to set the idle timeout interval to be used with on-demand
|
||||
@ -367,9 +380,13 @@ IPv6 DHCPv6-PD Example
|
||||
|
||||
.. stop_vyoslinter
|
||||
|
||||
The following configuration will assign a /64 prefix out of a /56 delegation
|
||||
to eth0. The IPv6 address assigned to eth0 will be <prefix>::ffff/64.
|
||||
If you do not know the prefix size delegated to you, start with sla-len 0.
|
||||
The following configuration will setup a PPPoE session source from eth1 and
|
||||
assign a /64 prefix out of a /56 delegation (requested from the ISP) to eth0.
|
||||
The IPv6 address assigned to eth0 will be <prefix>::1/64. If you do not know
|
||||
the prefix size delegated to you, start with sla-len 0.
|
||||
|
||||
In addition we setup IPv6 :abbr:`RA (Router Advertisements)` to make the
|
||||
prefix known on the eth0 link.
|
||||
|
||||
.. start_vyoslinter
|
||||
|
||||
@ -382,3 +399,5 @@ If you do not know the prefix size delegated to you, start with sla-len 0.
|
||||
set interfaces pppoe pppoe0 dhcpv6-options pd 0 length '56'
|
||||
set interfaces pppoe pppoe0 ipv6 address autoconf
|
||||
set interfaces pppoe pppoe0 source-interface eth1
|
||||
|
||||
set service router-advert interface eth0 prefix ::/64
|
||||
|
||||