├── .dockerignore
├── .gitignore
├── README.md
├── app.py
├── configs
└── .keep
├── dockerfile
├── docs
├── Makefile
├── image
│ └── main.png
├── make.bat
└── source
│ ├── _static
│ ├── Other_configs.png
│ ├── Policy.png
│ ├── chpoint
│ │ ├── ch_policy.png
│ │ └── configs.png
│ ├── palo
│ │ └── config_correction.png
│ └── srx
│ │ ├── Netconf.png
│ │ └── SRX_XML_Format.png
│ ├── chpoint.rst
│ ├── conf.py
│ ├── final.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── palo.rst
│ └── srx.rst
├── exported
└── .keep
├── logs
└── .keep
├── requirements.txt
└── resources
├── __init__.py
├── dst_vendor
├── __init__.py
├── dst_asa.py
├── dst_chpoint.py
├── dst_forti.py
├── dst_palo.py
└── dst_srx.py
├── ip_address_converter
└── netmask_convereter.py
├── parser.py
├── protocols
└── nc_conn.py
├── src_vendor
├── chpoint
│ ├── __init__.py
│ ├── chpoint_config_parser.py
│ └── chpoint_policy_parser.py
├── palo
│ ├── palo_config_coverter.py
│ └── palo_policy_convert.py
└── srx
│ ├── __init__.py
│ ├── srx_config_converter.py
│ └── srx_policy_convert.py
└── web
├── static
├── files.css
├── script.js
└── style.css
└── templates
├── exported_vendor.html
├── files.html
└── home.html
/.dockerignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.log
3 | __pycache__
4 | test.py
5 | .gitignore
6 | .dockerignore
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py,cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # poetry
98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99 | # This is especially recommended for binary packages to ensure reproducibility, and is more
100 | # commonly ignored for libraries.
101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102 | #poetry.lock
103 |
104 | # pdm
105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106 | #pdm.lock
107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108 | # in version control.
109 | # https://pdm.fming.dev/#use-with-ide
110 | .pdm.toml
111 |
112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113 | __pypackages__/
114 |
115 | # Celery stuff
116 | celerybeat-schedule
117 | celerybeat.pid
118 |
119 | # SageMath parsed files
120 | *.sage.py
121 |
122 | # Environments
123 | .env
124 | env/
125 | venv/
126 | ENV/
127 | env.bak/
128 | venv.bak/
129 | .venv*
130 |
131 | # Spyder project settings
132 | .spyderproject
133 | .spyproject
134 |
135 | # Rope project settings
136 | .ropeproject
137 |
138 | # mkdocs documentation
139 | /site
140 |
141 | # mypy
142 | .mypy_cache/
143 | .dmypy.json
144 | dmypy.json
145 |
146 | # Pyre type checker
147 | .pyre/
148 |
149 | # pytype static type analyzer
150 | .pytype/
151 |
152 | # Cython debug symbols
153 | cython_debug/
154 |
155 | # PyCharm
156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158 | # and can be added to the global gitignore or merged into this file. For a more nuclear
159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160 | #.idea/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Firewall Migration Tool
2 |
3 | fwmig tool helps you to migrate from one existing firewall to another one with simple copy/past steps.
4 |
5 | - It supports most well-known vendors.
6 | - This Tool is based on Flask and JS to provide Web UI for conversion of firewall objects and policies.
7 | - There is no online dependencies after you run the app.
8 | - Dockerfile is available for container implementaions.
9 | - Logging for troubleshoot is implemented.
10 | - Tested on python 3.8 and 3.9, and 3.10
11 |
12 | ----
13 | ## Run the code:
14 |
15 | ```sh
16 | python3.10 -m venv venv
17 | source venv/bin/activate
18 | pip install -r requirements.txt
19 | python app.py
20 | ```
21 | Or use Docker:
22 |
23 | ```sh
24 | docker build -t fwmig .
25 | docker run -p 8080:5000 --name=fwmig -d -v $(pwd)/logs:/code/logs/ -ti fwmig:latest
26 | ```
27 |
28 | -----
29 |
30 | ## Supported Matrix:
31 |
32 |
33 |
34 | Source Vendor |
35 | Destination Vendor |
36 |
37 |
38 | |
39 | Juniper SRX |
40 | Fortigate |
41 | Cisco ASA |
42 | Checkpoint |
43 | Palo Alto |
44 |
45 |
46 | Juniper SRX |
47 | N/A |
48 | Yes |
49 | Yes |
50 | Yes |
51 | Yes |
52 |
53 |
54 | Fortigate |
55 | No |
56 | N/A |
57 | No |
58 | No |
59 | No |
60 |
61 |
62 | Cisco ASA |
63 | No |
64 | No |
65 | N/A |
66 | No |
67 | No |
68 |
69 |
70 | Checkpoint |
71 | Yes |
72 | Yes |
73 | Yes |
74 | N/A |
75 | Yes |
76 |
77 |
78 | Palo Alto |
79 | Yes |
80 | Yes |
81 | Yes |
82 | Yes |
83 | N/A |
84 |
85 |
86 |
87 |
88 |
89 | 
90 |
91 | # Documentation
92 |
93 | Firewall Migration Tool (fwmig) documentation lives at [fwmig.readthedocs.io](https://fwmig.readthedocs.io/en/latest/?)
94 |
95 |
96 | # Feedback
97 |
98 | Please share your experience with me about Firewall Migration Tool through [@tavajjohi](https://twitter.com/tavajjohi) on twitter.
99 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from flask import Flask, flash, request, redirect, url_for, send_from_directory
4 | from flask.templating import render_template
5 | from werkzeug.utils import secure_filename
6 |
7 | from resources.parser import main_parser
8 | from resources import app_logger
9 |
10 | logger = app_logger()
11 |
12 | UPLOAD_FOLDER = 'configs/'
13 | ALLOWED_EXTENSIONS = {'txt', 'log', 'csv'}
14 |
15 | app = Flask(__name__, template_folder='resources/web/templates', static_folder='resources/web/static')
16 | app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
17 | app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
18 |
19 |
20 | def allowed_file(filename):
21 | return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
22 |
23 | @app.route('/', methods=['GET', 'POST'])
24 | def main():
25 | if request.method == 'POST':
26 | # check if the post request has the file part
27 | src_vendor = request.form.get('src_vendor')
28 | if request.form.get('type') == 'netconf':
29 | if src_vendor == 'srx':
30 | from resources.protocols.nc_conn import NcMGR
31 | acts = request.form.getlist('acts')
32 | action = request.form.get('action')
33 | nc_client = NcMGR()
34 | host = request.form.get('host')
35 | username = request.form.get('username')
36 | password = request.form.get('password')
37 | port = request.form.get('port')
38 | dst_vendor = request.form.get('dst_vendor')
39 | logger.info(f'Netconf started for {host} on port {port} ...')
40 | cfg = nc_client.junos_nc_conn(action, host, username, password, port, 'junos')
41 | if not cfg:
42 | flash('Authentication error')
43 | return redirect(request.url)
44 | elif cfg == 'other':
45 | flash('Connection problem, please check network and info.')
46 | return redirect(request.url)
47 | else:
48 | logger.info('Conversion started ...')
49 | main_parser(action, cfg, src_vendor, dst_vendor, acts)
50 | logger.info(f'Creating files and links for {dst_vendor}')
51 | return redirect(url_for('get_file', dirname=str(dst_vendor)))
52 | else:
53 | flash(f'Not supported for {src_vendor}!')
54 | return redirect(request.url)
55 | file = request.files['file']
56 | # if user does not select file, browser also
57 | # submit an empty part without filename
58 | if file.filename == '':
59 | flash('No selected file')
60 | return redirect(request.url)
61 | if file and allowed_file(file.filename):
62 | filename = secure_filename(file.filename)
63 | file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
64 | if src_vendor not in ['asa', 'forti']:
65 | acts = request.form.getlist('acts')
66 | action = request.form.get('action')
67 | if action == 'config' and not acts:
68 | flash('Please select one checkbox!')
69 | return redirect(request.url)
70 |
71 | dst_vendor = request.form.get('dst_vendor')
72 |
73 | logger.info('Conversion started ...')
74 | result = main_parser(action, filename, src_vendor, dst_vendor, acts)
75 |
76 | if not result:
77 | flash('Something is wrong! check again')
78 | return redirect(request.url)
79 | if result == 'no':
80 | flash('The operation is not supported for this vendor!')
81 | return redirect(request.url)
82 | logger.info(f'Creating files and links for {dst_vendor}')
83 | logger.info(50*'=')
84 | return redirect(url_for('get_file', dirname=str(dst_vendor)))
85 | else:
86 | flash('This conversion not supported yet.')
87 | return redirect(request.url)
88 |
89 | else:
90 | flash('File not supported. (txt, log, csv)')
91 | return redirect(request.url)
92 | return render_template('home.html')
93 |
94 | @app.route('/exported//') # this is a job for GET, not POST
95 | def get_file(dirname):
96 | dloads_dir = f'exported/{dirname}'
97 | dloads = os.listdir(dloads_dir)
98 | dloads_src = [f'/exported/{dirname}/{format(i)}' for i in dloads]
99 | return render_template('files.html', dloads=dloads, dloads_src=dloads_src, dirname=dirname)
100 |
101 |
102 | @app.route('/exported//')
103 | def download(dirname, filename):
104 | return send_from_directory(f'exported/{dirname}', filename)
105 |
106 |
107 | @app.route('/exported/')
108 | def exported():
109 | dloads_dir = 'exported/'
110 | dloads = os.listdir(dloads_dir)
111 | dloads_src = [f'/exported/{format(i)}' for i in dloads]
112 | return render_template('exported_vendor.html', dloads=dloads, dloads_src=dloads_src)
113 |
114 |
115 | if __name__ == "__main__":
116 | app.run(host='0.0.0.0')
--------------------------------------------------------------------------------
/configs/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/configs/.keep
--------------------------------------------------------------------------------
/dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.10-bullseye
2 |
3 | WORKDIR /code
4 |
5 | COPY requirements.txt requirements.txt
6 |
7 | RUN apt-get -y update
8 | RUN pip install -r requirements.txt
9 |
10 | EXPOSE 5000
11 |
12 | COPY . .
13 |
14 | CMD python app.py
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/image/main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/image/main.png
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/source/_static/Other_configs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/Other_configs.png
--------------------------------------------------------------------------------
/docs/source/_static/Policy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/Policy.png
--------------------------------------------------------------------------------
/docs/source/_static/chpoint/ch_policy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/chpoint/ch_policy.png
--------------------------------------------------------------------------------
/docs/source/_static/chpoint/configs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/chpoint/configs.png
--------------------------------------------------------------------------------
/docs/source/_static/palo/config_correction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/palo/config_correction.png
--------------------------------------------------------------------------------
/docs/source/_static/srx/Netconf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/srx/Netconf.png
--------------------------------------------------------------------------------
/docs/source/_static/srx/SRX_XML_Format.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/docs/source/_static/srx/SRX_XML_Format.png
--------------------------------------------------------------------------------
/docs/source/chpoint.rst:
--------------------------------------------------------------------------------
1 | Checkpoint conversion
2 | ######################
3 |
4 | It is tested on SmartConsle **CSV** policy and address object exporting format.
5 | Because of insufficient information on csv output, Service part does not have protocol part to understand wheter it is TCP/UDP and Service conversion not implemented yet.
6 |
7 | |
8 |
9 | File Base
10 | *********
11 |
12 | Here are steps to provide correct output file from Check Point:
13 |
14 | **Policy**:
15 |
16 | - Login to SmartConsole, go to **Security Policies**.
17 | - Click on actions and select export.
18 |
19 | .. image:: _static/chpoint/ch_policy.png
20 | :align: center
21 |
22 | |
23 |
24 | **Objects**:
25 |
26 | - Login to SmartConsole, on the right panel find 3 dots on toolbar and click.
27 | - Select Networks and Hosts section from left selection part
28 | - Click actions and select export.
29 |
30 | .. image:: _static/chpoint/configs.png
31 | :align: center
32 |
33 | |
34 |
35 | Final step
36 | **********
37 |
38 | Got to `After conversion `_
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | # import os
14 | # import sys
15 | # sys.path.insert(0, os.path.abspath('.'))
16 |
17 |
18 | # -- Project information -----------------------------------------------------
19 |
20 | project = 'Firewall Migration Tool (fwmig)'
21 | copyright = '2021, Vahid Tavajjohi'
22 | author = 'Vahid Tavajjohi'
23 |
24 | # The full version, including alpha/beta/rc tags
25 | release = '0.2.0'
26 |
27 |
28 | # -- General configuration ---------------------------------------------------
29 |
30 | # Add any Sphinx extension module names here, as strings. They can be
31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
32 | # ones.
33 | extensions = [
34 | ]
35 |
36 | # Add any paths that contain templates here, relative to this directory.
37 | templates_path = ['_templates']
38 |
39 | # List of patterns, relative to source directory, that match files and
40 | # directories to ignore when looking for source files.
41 | # This pattern also affects html_static_path and html_extra_path.
42 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
43 |
44 |
45 | # -- Options for HTML output -------------------------------------------------
46 |
47 | # The theme to use for HTML and HTML Help pages. See the documentation for
48 | # a list of builtin themes.
49 | #
50 | html_theme = 'alabaster'
51 |
52 | # Add any paths that contain custom static files (such as style sheets) here,
53 | # relative to this directory. They are copied after the builtin static files,
54 | # so a file named "default.css" will overwrite the builtin "default.css".
55 | html_static_path = ['_static']
56 |
57 | html_theme_options = {
58 | "show_powered_by": False,
59 | "github_user": "vahidta",
60 | "github_repo": "firewall_migration_tool",
61 | "github_banner": True,
62 | "github_button": True,
63 | "github_type": "star",
64 | "show_related": False,
65 | }
--------------------------------------------------------------------------------
/docs/source/final.rst:
--------------------------------------------------------------------------------
1 | After Conversion
2 | ################
3 |
4 | After successfull conversion of source config, based on destination vendor you were selected you must follow reagarding steps.
5 |
6 |
7 | Cisco ASA
8 | *********
9 |
10 | Cisco ASA policy works only for global policy.
11 |
12 | - Login to the device
13 | - Enter to global config mode
14 | - You must copy/paste configuration first and then configuration.
15 | - Each .txt file contains related configuration.
16 |
17 |
18 | Checkpoint
19 | **********
20 |
21 | * It supports from release R80 and later.
22 | * API must be enabled. Please refer to Checkpoint documentation.
23 | * Network and Service Objects will force to replace if there is existing object with the same name.
24 | * For objects, login to the device and go to expert mode
25 | * Use these steps:
26 |
27 | .. code-block:: bash
28 | :linenos:
29 |
30 | mgmt_cli add host --batch network_objects_host.csv #Host objects
31 | mgmt_cli add network --batch network_objects_network.csv #Network with subnets
32 | mgmt_cli add group --batch network_groups.csv #Object group objects
33 | mgmt_cli set group --batch network_group_members.csv #Object group members
34 | mgmt_cli add service-group --batch service_groups.csv #Service group members
35 | mgmt_cli set service-group --batch service_groups_members.csv #Service group members
36 |
37 | * For Policies:
38 | * Set ``username`` and ``password`` inside the ``policies.txt``.
39 | * Login to the decvice and go to expert mode. Then paste output policy.
40 | * This method is using `sid` for authentication.
41 | * Because of the platform limitations, you must paste rules by grouping 3 or 4 rules for each copy.
42 | * Please note that about per 100 lines there is a ``publish`` action.
43 |
44 |
45 | Fortigate
46 | *********
47 |
48 | Because of the platform limitations, Policy names will be support upto 35 charachters. So, if there is a policy name with more than 35 charachter length will be convert to only first 35 characters.
49 |
50 | * Login to the device
51 | * You must copy/paste configuration first and then configuration.
52 |
53 | Palo Alto
54 | *********
55 |
56 | May not allow more than 30 inputs in one copy/paste. So partition the output in clipboard.
57 |
58 | * Login to the device
59 | * Enter to config mode
60 | * You must copy/paste configuration first and then configuration
61 | * Commit the configuration at the end
62 |
63 |
64 | Juniper SRX
65 | ***********
66 |
67 | For SRX, output file is "set" based.
68 |
69 | * Login to the device
70 | * Enter to config mode
71 | * You must copy/paste configuration first and then configuration
72 | * Commit the configuration at the end
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | Firewall Migration Tool (fwmig)
2 | ###############################
3 |
4 | fwmig tool helps you to migrate from one existing firewall to another one with simple copy/past steps.
5 |
6 | - It supports most well-known vendors.
7 | - This tool is based on Flask and JS to provide Web UI for conversion of firewall objects and policies.
8 | - There is no online dependencies after you run the app.
9 | - Dockerfile is available for container implementaions.
10 | - Logging for troubleshoot is implemented.
11 | - Tested on python 3.8, 3.9, and 3.10
12 |
13 | |
14 |
15 | Supported Matrix table:
16 |
17 | ================ ====== ========== ========== =========== ===========
18 | Source Vendor Destination Vendor
19 | ---------------- --------------------------------------------------------
20 | .. SRX Fortigate Cisco ASA Checkpoint Palo Alto
21 | ================ ====== ========== ========== =========== ===========
22 | **SRX** N/A Yes Yes Yes Yes
23 | ---------------- ------ ---------- ---------- ----------- -----------
24 | **Fortigate** No N/A No No No
25 | ---------------- ------ ---------- ---------- ----------- -----------
26 | **Cisco ASA** No No N/A No No
27 | ---------------- ------ ---------- ---------- ----------- -----------
28 | **Checkpoint** Yes Yes Yes N/A Yes
29 | ---------------- ------ ---------- ---------- ----------- -----------
30 | **Palo Alto** Yes Yes Yes Yes N/A
31 | ================ ====== ========== ========== =========== ===========
32 |
33 | |
34 |
35 | Any predefined services that are not included in fwmig or are not defined on the destination vendor (e.g., Palo Alto) will remain the same as on the source platform. For example, if there is an object called ``junos-who`` that this tool cannot convert, you will find an ``Error`` in the description of the policy it uses.
36 |
37 | |
38 |
39 | .. warning::
40 | This tool **does not** support Zone, Interfaces, and NAT conversion yet. Please note that you **must** create interfaces and Zones before using policy output.
41 |
42 | Getting Start:
43 | ==============
44 | .. toctree::
45 | :maxdepth: 2
46 |
47 | installation
48 | srx
49 | palo
50 | chpoint
51 | final
52 |
53 |
54 | Feedback
55 | ********
56 |
57 | Please share your experience with me about Firewall Migration Tool through `@tavajjohi `_ on twitter.
--------------------------------------------------------------------------------
/docs/source/installation.rst:
--------------------------------------------------------------------------------
1 | Installation
2 | ############
3 |
4 | Here are two option for using firewall migration tool:
5 |
6 | Bash
7 | ****
8 |
9 | - Make a clone from the `Firewall Migration Tool `_ link
10 | - Use ``pip install -r requirements.txt`` to install required packages
11 | - Start the app using ``python3 app.py``
12 | - Connect to ``http://localhost:5000`` on browser.
13 |
14 | Container
15 | *********
16 |
17 | - Make a clone from the `Firewall Migration Tool `_ link
18 | - To build and run container use:
19 |
20 | .. code-block:: bash
21 | :linenos:
22 |
23 | docker build -t fwmig:latest
24 | docker run -p 8080:5000 --name=fwmig -d -v $(pwd)/logs:/code/logs/ -ti fwmig:latest
25 |
26 | - Connect to ``http://127.0.0.1:8080`` on browser.
--------------------------------------------------------------------------------
/docs/source/palo.rst:
--------------------------------------------------------------------------------
1 | Palo Alto conversion
2 | ####################
3 |
4 | As Palo alto supports XML output format, here is the steps for getting config and policy fro PAN-OS:
5 |
6 | File Base
7 | *********
8 |
9 | **Policy and Config**
10 |
11 | - Login to PAN-OS through cli or console.
12 | - Execute ``set cli config-output-format xml`` command
13 | - Enter to config mode with ``configure``
14 | - Execute ``show`` command
15 | - Copy the output into file
16 | - Supported file extensions is .log and .txt
17 | - Because of Palo Alto XML formatted that is not standard, it is important to wrap up entire output with and tag.
18 |
19 | .. image:: _static/palo/config_correction.png
20 | :align: center
21 |
22 | |
23 |
24 | Final step
25 | **********
26 |
27 | Got to `After conversion `_
--------------------------------------------------------------------------------
/docs/source/srx.rst:
--------------------------------------------------------------------------------
1 | SRX conversion
2 | ##############
3 |
4 | It is tested on Junos 12.x , 15.x , 18.x and it uses XML format to convert configs and policies.
5 | Policies can not be extracted from SRX configuration output, because it does not provide **rule order** . So, from ``show security policies`` it can find out rule/policy orders.
6 |
7 | Features
8 | ========
9 | - Address books (Global and Policy based)
10 | - Name
11 | - Description
12 |
13 | - Services and Service Groups
14 | - Name
15 | - Description
16 | - Source and Destination port
17 | - Session timeout
18 |
19 | |
20 |
21 | File Base
22 | *********
23 |
24 | If you want to get the SRX device configs and policies manually, you need to select ``file`` under ``Type of conversion`` section and you can follow below steps to do conversion without any error.
25 |
26 | SRX config and policy
27 | =====================
28 |
29 | Here are steps to provide correct output file from SRX devices:
30 |
31 | **Policy**:
32 |
33 | - Login to SRX and execute :code:`show security policies | display xml`
34 | - Copy the output into file
35 | - Make sure only XML output is in the file
36 | - Supported file extensions is .log and .txt
37 |
38 | **General configs**:
39 |
40 | - Login to SRX and execute :code:`show configuration | display xml`
41 | - Copy the output into file
42 | - Make sure only XML output is in the file
43 | - Supported file extensions is .log and .txt
44 |
45 |
46 | For example if file starts or ends with some not xml lines please remove them. In below figure you can see first line is not xml formatted:
47 |
48 | .. image:: _static/srx/SRX_XML_Format.png
49 | :align: center
50 |
51 | It is important to note that after conversion steps, you must paste output files of configuration first. Because, policies uses network/service objects and if they are not available on destination device, policies will be failed.
52 |
53 |
54 | Using conversion
55 | ================
56 |
57 | After `SRX Config and policy`_ steps, you can upload file through web UI. For policy conversion you should choose ``policy`` option under ``Action`` on web UI and upload policy XML formatted file to upload. However, if you choose ``other configs``, new options will be available for Address Books, Services and Service-groups to provide better result. You can see below figure for both options.
58 |
59 | .. image:: _static/Policy.png
60 | :width: 48 %
61 | .. image:: _static/Other_configs.png
62 | :width: 48 %
63 |
64 |
65 | |
66 |
67 | Netconf
68 | *******
69 |
70 | You can use Netconf for conversion in fwmig. It will connect to the srx device and read configs or policies and then it will converts to destination vendor. You need to provide access for fwmig on Netconf port (TCP/22 or TCP/830) on SRX device. Below figure is example of Netconf conversion:
71 |
72 | .. image:: _static/srx/Netconf.png
73 | :align: center
74 |
75 | |
76 |
77 | Final step
78 | **********
79 |
80 | Go to `After conversion `_
--------------------------------------------------------------------------------
/exported/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/exported/.keep
--------------------------------------------------------------------------------
/logs/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/logs/.keep
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask==2.2.5
2 | ncclient==0.6.9
3 | pandas==1.3.4
4 | paramiko==2.7.2
5 | requests==2.25.1
6 | xmltodict==0.12.0
7 |
--------------------------------------------------------------------------------
/resources/__init__.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from logging.handlers import RotatingFileHandler
4 |
5 | def app_logger():
6 |
7 | log_date = '%Y-%m-%d %H:%M:%S'
8 | log_format = '%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s'
9 | handler = RotatingFileHandler('logs/app.log', maxBytes=100000, backupCount=1)
10 | formatter = logging.Formatter(log_format, log_date)
11 | handler.setFormatter(formatter)
12 | handler.suffix = f'%Y-%m-%d.log'
13 | handler.setLevel(logging.INFO)
14 |
15 | logger = logging.getLogger('fwmig')
16 | logger.setLevel(logging.INFO)
17 | logger.addHandler(handler)
18 |
19 | return logger
20 |
--------------------------------------------------------------------------------
/resources/dst_vendor/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/resources/dst_vendor/__init__.py
--------------------------------------------------------------------------------
/resources/dst_vendor/dst_asa.py:
--------------------------------------------------------------------------------
1 | from resources.ip_address_converter.netmask_convereter import netmasker, nethost
2 |
3 | class ASA_DST:
4 |
5 | def service(*args):
6 | application_name = args[1]
7 | destination_port = args[2]
8 | source_port = args[3]
9 | application_protocol = args[4]
10 | application_desc = args[5]
11 |
12 | with open('exported/asa/service_objects.txt', 'a') as f:
13 | f.write(f'object service {application_name}\n')
14 | if destination_port:
15 | if '-' in destination_port:
16 | destination_port = destination_port.replace('-', ' ')
17 | f.write(f'service {application_protocol} destination range {destination_port}\n')
18 | else:
19 | f.write(f'service {application_protocol} destination eq {destination_port}\n')
20 | elif source_port:
21 | if '-' in source_port:
22 | source_port = source_port.replace('-', ' ')
23 | f.write(f'service {application_protocol} source range {source_port}\n')
24 | else:
25 | f.write(f'service {application_protocol} source eq {source_port}\n')
26 | if application_desc:
27 | f.write(f'description {application_desc} \n')
28 | f.write('exit\n\n')
29 |
30 | def service_set(*args):
31 | app_set_name = args[1]
32 | app_list = args[2]
33 | app_set_desc = args[3]
34 |
35 | with open('exported/asa/service_object_group.txt', 'a') as f:
36 | f.write(f'object-group service {app_set_name}\n')
37 | for object in app_list:
38 | if isinstance(object, (list)):
39 | if object[0] == 'icmp':
40 | f.write(f'service-object {object[0]} {object[1]}\n')
41 | else:
42 | f.write(f'service-object {object[0]} destination eq {object[1]}\n')
43 | else:
44 | f.write(f'service-object object {object} \n')
45 | if app_set_desc:
46 | f.write(f'description "{app_set_desc}" \n')
47 | f.write('exit\n\n')
48 |
49 | def address(*args):
50 | address_name = args[1]
51 | address_ip = args[2]
52 | address_desc = args[3]
53 |
54 | with open('exported/asa/object_network.txt', 'a') as f:
55 | if '-' in address_ip:
56 | start_ip = address_ip.split('-')[0].replace(' ', '')
57 | end_ip = address_ip.split('-')[1].replace(' ', '')
58 | address_netmask = f'range {start_ip} {end_ip}'
59 | elif '/32' in address_ip:
60 | address_netmask = 'host ' + nethost(address_ip)
61 | else:
62 | address_netmask = 'subnet ' + netmasker(address_ip)
63 | if '/' in address_name:
64 | address_name = address_name.replace('/', '-')
65 | f.write(f'object network {address_name}\n')
66 | if address_desc:
67 | f.write(f'description {address_desc}\n')
68 | f.write(f'{address_netmask}\n')
69 | f.write('exit\n\n')
70 |
71 |
72 | def address_set(*args):
73 | address_set_name = args[1]
74 | address_name_list = args[2]
75 | address_set_desc = args[3]
76 |
77 | with open('exported/asa/object_group_network.txt', 'a') as f:
78 | f.write(f'object-group network {address_set_name}\n')
79 | if address_set_desc:
80 | f.write(f'description {address_set_desc}\n')
81 | for address_name in address_name_list:
82 | f.write(f'network-object object {address_name}\n')
83 | f.write('exit\n\n')
84 |
85 | def policy(*args):
86 | """Not Implemented"""
87 | policy_name = args[1]
88 | source_zone = args[2]
89 | destination_zone = args[3]
90 | policy_src_address = args[4]
91 | policy_dst_address = args[5]
92 | policy_app = args[6]
93 | policy_log = args[7]
94 | policy_state = args[8]
95 | policy_action = args[9]
96 | policy_id = args[10]
97 |
98 | the_path = 'exported/asa/policies.txt'
99 | if policy_state != 'inactive':
100 | policy_state = ''
101 | if policy_log:
102 | policy_log = 'log'
103 | else:
104 | policy_log = ''
105 | if ' ' in policy_src_address:
106 | src_group_name = f'DM_INLINE_NETWORK_111{policy_id}'
107 | with open(the_path, 'a') as output:
108 | output.write(f'object-group network {src_group_name}\n')
109 | for src in policy_src_address.split(' '):
110 | output.write(f' network-object object {src}\n')
111 | output.write(' exit\n\n')
112 | policy_src_address = f'object-group {src_group_name}'
113 | else:
114 | policy_src_address = f'object {policy_src_address}'
115 | if ' ' in policy_dst_address:
116 | dst_group_name = f'DM_INLINE_NETWORK_222{policy_id}'
117 | with open(the_path, 'a') as output:
118 | output.write(f'object-group network {dst_group_name}\n')
119 | for dst in policy_dst_address.split(' '):
120 | output.write(f' network-object object {dst}\n')
121 | output.write(' exit\n\n')
122 | policy_dst_address = f'object-group {dst_group_name}'
123 | else:
124 | policy_dst_address = f'object {policy_dst_address}'
125 |
126 | if ' ' in policy_app:
127 | app_group_name = f'DM_INLINE_SERVICE_333{policy_id}'
128 | with open(the_path, 'a') as output:
129 | output.write(f'object-group service {app_group_name}\n')
130 | for dst in policy_app.split(' '):
131 | if isinstance(dst, (list)):
132 | if dst[1] == 'na':
133 | output.write(f' service-object {dst[0]}\n')
134 | else:
135 | dst = f'{dst[0]} destionation eq {dst[1]}'
136 | output.write(f' service-object {dst}\n')
137 | else:
138 | output.write(f' service-object object {dst}\n')
139 | policy_app = f'object-group {app_group_name}'
140 | elif isinstance(policy_app, (list)):
141 | app_group_name = f'DM_INLINE_SERVICE_333{policy_id}'
142 | with open(the_path, 'a') as output:
143 | output.write(f'object-group service {app_group_name}\n')
144 | for dst in policy_app:
145 | if isinstance(dst, (list)):
146 | if dst[1] == 'na':
147 | output.write(f' service-object {dst[0]}\n')
148 | else:
149 | dst = f'{dst[0]} destionation eq {dst[1]}'
150 | output.write(f' service-object {dst}\n')
151 | else:
152 | output.write(f' service-object object {dst}\n')
153 | policy_app = f'object-group {app_group_name}'
154 |
155 | if (isinstance(policy_app, (list)) == False) and ('DM_INLINE_SERVICE_' in policy_app) == False:
156 | policy_app = f'object {policy_app}'
157 | # if ('DM_INLINE_SERVICE_' in policy_app) == False:
158 | # policy_app = f'object {policy_app}'
159 |
160 | if isinstance(policy_app, (list)):
161 | with open('exported/asa/policies.txt', 'a') as output:
162 | output.write(f'access-list global_access line {policy_id} extended {policy_action} {policy_app[0]} {policy_src_address} {policy_dst_address} eq {policy_app[1]} {policy_log} {policy_state}\n\n')
163 | else:
164 | with open('exported/asa/policies.txt', 'a') as output:
165 | output.write(f'access-list global_access line {policy_id} extended {policy_action} {policy_app} {policy_src_address} {policy_dst_address} {policy_log} {policy_state}\n\n')
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/resources/dst_vendor/dst_chpoint.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from resources.ip_address_converter.netmask_convereter import nethost, sub_mask
4 |
5 |
6 | class CHPoint_DST:
7 |
8 | def service(*args):
9 | application_name = args[1]
10 | destination_port = args[2]
11 | source_port = args[3]
12 | application_protocol = args[4]
13 | application_desc = args[5]
14 | app_session_ttl = args[6]
15 |
16 | the_path = f'exported/chpoint/service-{application_protocol}.csv'
17 | with open(the_path, 'a') as f:
18 | if os.path.getsize(the_path) == 0:
19 | f.write('name,port,source-port,session-timeout,set-if-exists,ignore-warnings,ignore-errors,comments\n')
20 | if application_desc and destination_port:
21 | f.write(f'{application_name},{destination_port},{source_port},{app_session_ttl},true,true,true,"{application_desc}"\n')
22 | elif destination_port:
23 | f.write(f'{application_name},{destination_port},{source_port},{app_session_ttl},true,true,true,\n')
24 |
25 | def service_set(*args):
26 | app_set_name = args[1]
27 | app_list = args[2]
28 | app_set_desc = args[3]
29 |
30 | the_path = 'exported/chpoint/service_groups.csv'
31 | with open(the_path, 'a') as f:
32 | if os.path.getsize(the_path) == 0:
33 | f.write('name,ignore-warnings,ignore-errors,comments\n')
34 | if app_set_desc:
35 | f.write(f'{app_set_name},true,true,"{app_set_desc}"\n')
36 | else:
37 | f.write(f'{app_set_name},true,true,\n')
38 | the_path = 'exported/chpoint/service_groups_members.csv'
39 | with open(the_path, 'a') as f:
40 | if os.path.getsize(the_path) == 0:
41 | f.write('name,members.add,ignore-warnings,ignore-errors\n')
42 | for object in app_list:
43 | if object[:1].isdigit():
44 | object = 'custom_' + object
45 | f.write(f'{app_set_name},{object},true,true\n')
46 |
47 | def address(*args):
48 | address_name = args[1]
49 | address_ip = args[2]
50 | address_desc = args[3]
51 |
52 | if '/32' in address_ip:
53 | address_netmask = nethost(address_ip)
54 | the_path = 'exported/chpoint/network_objects_host.csv'
55 | with open(the_path, 'a') as f:
56 | if os.path.getsize(the_path) == 0:
57 | f.write(f'name,ip-address,set-if-exists,ignore-warnings,ignore-errors,comments\n')
58 | if address_desc:
59 | f.write(f'{address_name},{address_netmask},true,true,true,"{address_desc}"\n')
60 | else:
61 | f.write(f'{address_name},{address_netmask},true,true,true,\n')
62 | else:
63 | add_subnet = nethost(address_ip)
64 | add_mask = sub_mask(address_ip)
65 | the_path = 'exported/chpoint/network_objects_network.csv'
66 | with open(the_path, 'a') as f:
67 | if os.path.getsize(the_path) == 0:
68 | f.write(f'name,subnet,subnet-mask,set-if-exists,ignore-warnings,ignore-errors,comments\n')
69 | if address_desc:
70 | f.write(f'{address_name},{add_subnet},{add_mask},true,true,true,"{address_desc}"\n')
71 | else:
72 | f.write(f'{address_name},{add_subnet},{add_mask},true,true,true,\n')
73 |
74 |
75 | def address_set(*args):
76 | address_set_name = args[1]
77 | address_name_list = args[2]
78 | address_set_desc = args[3]
79 |
80 | the_path = 'exported/chpoint/network_groups.csv'
81 | with open(the_path, 'a') as f:
82 | if os.path.getsize(the_path) == 0:
83 | f.write(f'name,ignore-warnings,ignore-errors,comments\n')
84 | if address_set_desc:
85 | f.write(f'{address_set_name},true,true,"{address_set_desc}"\n')
86 | else:
87 | f.write(f'{address_set_name},true,true,\n')
88 |
89 | the_path = 'exported/chpoint/network_group_members.csv'
90 | with open(the_path, 'a') as f:
91 | if os.path.getsize(the_path) == 0:
92 | f.write(f'name,members.add,ignore-warnings,ignore-errors\n')
93 | for address_name in address_name_list:
94 | f.write(f'{address_set_name},{address_name},true,true\n')
95 |
96 | def policy(*args):
97 | policy_name = args[1]
98 | source_zone = args[2]
99 | destination_zone = args[3]
100 | policy_src_address = args[4]
101 | policy_dst_address = args[5]
102 | policy_app = args[6]
103 | policy_log = args[7]
104 | policy_state = args[8]
105 | policy_action = args[9]
106 | policy_id = args[10]
107 | position = args[11]
108 |
109 | the_path = 'exported/chpoint/policies.txt'
110 | with open(the_path, 'a') as output:
111 | if os.path.getsize(the_path) == 0:
112 | output.write('mgmt_cli login -u "your username" -p "your password" > "sid.txt"\n\n')
113 |
114 | if policy_log:
115 | output.write(f'mgmt_cli add access-rule layer "Network" position "{position}" name "{policy_name}" action "{policy_action}" {policy_src_address} {policy_dst_address} {policy_app} enabled {policy_state} comments "original rule order {policy_id}" track Log -s "sid.txt"\n\n')
116 |
117 | else:
118 | output.write(f'mgmt_cli add access-rule layer "Network" position "{position}" name "{policy_name}" action "{policy_action}" {policy_src_address} {policy_dst_address} {policy_app} enabled {policy_state} comments "original rule order{policy_id}" -s "sid.txt"\n\n')
119 |
120 | if position != 0 and position % 53 == 0:
121 | output.write('mgmt_cli publish -s "sid.txt"\n\n')
--------------------------------------------------------------------------------
/resources/dst_vendor/dst_forti.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | class Forti_DST:
4 |
5 | def service(*args):
6 | application_name = args[1]
7 | destination_port = args[2]
8 | source_port = args[3]
9 | application_protocol = args[4]
10 | application_desc = args[5]
11 | app_session_ttl = args[6]
12 |
13 |
14 | the_path = 'exported/forti/services.txt'
15 | with open(the_path, 'a') as f:
16 | if os.path.getsize(the_path) == 0:
17 | f.write(f'config firewall service custom\n\n')
18 |
19 | f.write(f'edit {application_name}\n')
20 | if destination_port and not source_port:
21 | f.write(f'set {application_protocol}-portrange {destination_port}\n')
22 | elif source_port and not destination_port:
23 | f.write(f'set {application_protocol}-portrange {source_port}\n')
24 | elif source_port and destination_port:
25 | f.write(f'set {application_protocol}-portrange {destination_port}:{source_port}\n')
26 | if app_session_ttl:
27 | f.write(f'set session-ttl {app_session_ttl}\n')
28 | if application_desc:
29 | f.write(f'set comment "{application_desc}"\n')
30 |
31 | f.write('next\n\n')
32 |
33 | def service_set(*args):
34 | app_set_name = args[1]
35 | app_name = args[2]
36 | app_set_desc = args[3]
37 |
38 | the_path = 'exported/forti/service_group.txt'
39 | with open(the_path, 'a') as f:
40 | if os.path.getsize(the_path) == 0:
41 | f.write(f'config firewall service group\n\n')
42 | f.write(f'edit {app_set_name}\n')
43 | f.write(f'set member {app_name}\n')
44 | if app_set_desc:
45 | f.write(f'set comment "{app_set_desc}"\n')
46 | f.write('next\n\n')
47 |
48 | def address(*args):
49 | address_name = args[1]
50 | address_ip = args[2]
51 | address_desc = args[3]
52 |
53 | the_path = 'exported/forti/addresses.txt'
54 | with open(the_path, 'a') as f:
55 | if os.path.getsize(the_path) == 0:
56 | f.write('config firewall address\n\n')
57 | f.write(f'edit {address_name}\n')
58 | if address_desc:
59 | f.write(f'set comment "{address_desc}"\n')
60 | if '-' in address_ip:
61 | f.write(f'set type iprange\n')
62 | start_ip = address_ip.split('-')[0].replace(' ', '')
63 | end_ip = address_ip.split('-')[1].replace(' ', '')
64 | f.write(f'set start-ip {start_ip}\n')
65 | f.write(f'set end-ip {end_ip}\n')
66 | else:
67 | f.write(f'set subnet {address_ip}\n')
68 | f.write('next\n\n')
69 |
70 |
71 | def address_set(*args):
72 | address_set_name = args[1]
73 | address_name = args[2]
74 | address_set_desc = args[3]
75 |
76 | the_path = 'exported/forti/address_group.txt'
77 | with open(the_path, 'a') as f:
78 | if os.path.getsize(the_path) == 0:
79 | f.write('config firewall addrgrp\n\n')
80 | f.write(f'edit {address_set_name}\n')
81 | f.write(f'set member {address_name}\n')
82 | if address_set_desc:
83 | f.write(f'set comment "{address_set_desc}"\n')
84 | f.write('next\n\n')
85 |
86 | def policy(*args):
87 | policy_name = args[1]
88 | source_zone = args[2]
89 | destination_zone = args[3]
90 | policy_src_address = args[4]
91 | policy_dst_address = args[5]
92 | policy_app = args[6]
93 | policy_log = args[7]
94 | policy_state = args[8]
95 | policy_action = args[9]
96 | policy_id = args[10]
97 |
98 | the_path = 'exported/forti/policies.txt'
99 | with open(the_path, 'a') as output:
100 | if os.path.getsize(the_path) == 0:
101 | output.write('config firewall policy\n\n')
102 | output.write(f'edit {policy_id}\n')
103 | output.write(f'set name {policy_name}\n')
104 | output.write(f'set srcintf {source_zone}\n')
105 | output.write(f'set dstintf {destination_zone}\n')
106 | output.write(f'set srcaddr {policy_src_address}\n')
107 | output.write(f'set dstaddr {policy_dst_address}\n')
108 | output.write(f'set action {policy_action}\n')
109 | output.write(f'set service {policy_app}\n')
110 | if policy_log:
111 | output.write(f'set logtraffic all\n')
112 | if 'junos' in policy_app:
113 | output.write(f'set comments "Error, please check service for correction!"\n')
114 | output.write(f'set status {policy_state}\n')
115 | output.write('set schedule always\n')
116 | output.write('next\n\n')
--------------------------------------------------------------------------------
/resources/dst_vendor/dst_palo.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | class Palo_DST:
4 |
5 | def service(*args):
6 | application_name = args[1]
7 | destination_port = args[2]
8 | source_port = args[3]
9 | application_protocol = args[4]
10 | application_desc = args[5]
11 | app_session_ttl = args[6]
12 |
13 | with open('exported/palo/services.txt', 'a') as f:
14 | if destination_port:
15 | f.write(f'set service {application_name} protocol {application_protocol} port {destination_port}\n\n')
16 | elif source_port:
17 | f.write(f'set service {application_name} protocol {application_protocol} source-port {source_port}\n\n')
18 | if application_desc:
19 | f.write(f'set service {application_name} description "{application_desc}"\n\n')
20 | if app_session_ttl:
21 | f.write(f'set service {application_name} protocol {application_protocol} override yes timeout {app_session_ttl}\n\n')
22 |
23 |
24 |
25 | def service_set(*args):
26 | app_set_name = args[1]
27 | app_name = args[2]
28 |
29 | with open('exported/palo/service_group.txt', 'a') as f:
30 | f.write(f'set service-group {app_set_name} members [ {app_name} ]\n\n')
31 |
32 | def address(*args):
33 | address_name = args[1]
34 | address_ip = args[2]
35 | address_desc = args[3]
36 |
37 | with open('exported/palo/addresses.txt', 'a') as f:
38 | if '-' in address_ip:
39 | address_ip = address_ip.replace(' ', '')
40 | f.write(f'set address {address_name} ip-range {address_ip}\n\n')
41 | else:
42 | f.write(f'set address {address_name} ip-netmask {address_ip}\n\n')
43 | if address_desc:
44 | f.write(f'set address {address_name} description "{address_desc}"\n\n')
45 |
46 | def address_set(*args):
47 | address_set_name = args[1]
48 | address_name = args[2]
49 | address_set_desc = args[3]
50 |
51 | with open('exported/palo/address_group.txt', 'a') as f:
52 | f.write(f'set address-group {address_set_name} static [ {address_name} ]\n\n')
53 | if address_set_desc:
54 | f.write(f'set address-group {address_set_name} description "{address_set_desc}"\n\n')
55 |
56 | def policy(*args):
57 | policy_name = args[1]
58 | source_zone = args[2]
59 | destination_zone = args[3]
60 | policy_src_address = args[4]
61 | policy_dst_address = args[5]
62 | policy_app = args[6]
63 | policy_log = args[7]
64 | policy_state = args[8]
65 | policy_action = args[9]
66 |
67 | the_path = 'exported/palo/policies.txt'
68 | with open(the_path, 'a') as output:
69 | if os.path.getsize(the_path) == 0:
70 | output.write('edit rulebase security\n\n')
71 | output.write(f'set rules {policy_name} from {source_zone}\n')
72 | output.write(f'set rules {policy_name} to {destination_zone}\n')
73 | output.write(f'set rules {policy_name} source [ {policy_src_address} ]\n')
74 | output.write(f'set rules {policy_name} destination [ {policy_dst_address} ]\n')
75 | output.write(f'set rules {policy_name} service [ {policy_app} ]\n')
76 | output.write(f'set rules {policy_name} application any\n')
77 | if source_zone == destination_zone:
78 | output.write(f'set rules {policy_name} rule-type intrazone\n')
79 | else:
80 | output.write(f'set rules {policy_name} rule-type interzone\n')
81 | if policy_log:
82 | output.write(f'set rules {policy_name} log-start yes\n')
83 | if policy_state == 'disabled':
84 | output.write(f'set rules {policy_name} disabled yes\n')
85 | output.write(f'set rules {policy_name} action {policy_action}\n\n')
86 |
--------------------------------------------------------------------------------
/resources/dst_vendor/dst_srx.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | class SRX_DST:
4 |
5 | def service(*args):
6 | application_name = args[1]
7 | destination_port = args[2]
8 | source_port = args[3]
9 | application_protocol = args[4]
10 | application_desc = args[5]
11 | app_session_ttl = args[6]
12 |
13 | with open('exported/srx/services.txt', 'a') as f:
14 | if destination_port:
15 | f.write(f'set service {application_name} protocol {application_protocol} port {destination_port}\n\n')
16 | elif source_port:
17 | f.write(f'set service {application_name} protocol {application_protocol} source-port {source_port}\n\n')
18 | if application_desc:
19 | f.write(f'set service {application_name} description "{application_desc}"\n\n')
20 |
21 | def service_set(*args):
22 | app_set_name = args[1]
23 | app_name = args[2]
24 |
25 | with open('exported/srx/service_group.txt', 'a') as f:
26 | f.write(f'set service-group {app_set_name} members [ {app_name} ]\n\n')
27 |
28 | def address(*args):
29 | address_name = args[1]
30 | address_ip = args[2]
31 | address_desc = args[3]
32 |
33 | the_path = 'exported/srx/addresses.txt'
34 | with open(the_path, 'a') as f:
35 | if os.path.getsize(the_path) == 0:
36 | f.write(f'edit security address-book global\n\n')
37 | if '-' in address_ip:
38 | start_ip = address_ip.split('-')[0].replace(' ', '')
39 | end_ip = address_ip.split('-')[1].replace(' ', '')
40 | f.write(f'set address {address_name} range-address {start_ip} to {end_ip}\n\n')
41 | else:
42 | f.write(f'set address {address_name} ip-netmask {address_ip}\n\n')
43 | if address_desc:
44 | f.write(f'set address {address_name} description "{address_desc}"\n\n')
45 |
46 | def address_set(*args):
47 | address_set_name = args[1]
48 | address_name = args[2]
49 | address_set_desc = args[3]
50 |
51 | with open('exported/srx/address_group.txt', 'a') as f:
52 | f.write(f'set address-group {address_set_name} static [ {address_name} ]\n\n')
53 | if address_set_desc:
54 | f.write(f'set address-group {address_set_name} description "{address_set_desc}"\n\n')
55 |
56 | def policy(*args):
57 | policy_name = args[1]
58 | source_zone = args[2]
59 | destination_zone = args[3]
60 | policy_src_address = args[4]
61 | policy_dst_address = args[5]
62 | policy_app = args[6]
63 | policy_log = args[7]
64 | policy_state = args[8]
65 | policy_action = args[9]
66 |
67 | the_path = 'exported/srx/policies.txt'
68 | with open(the_path, 'a') as output:
69 | if os.path.getsize(the_path) == 0:
70 | output.write('edit security policies\n\n')
71 | if source_zone == 'global' and destination_zone == 'global':
72 | output.write(f'set global policy {policy_name} match source-address [ {policy_src_address} ]\n')
73 | output.write(f'set global policy {policy_name} match destination-address [ {policy_src_address} ]\n')
74 | output.write(f'set global policy {policy_name} match application [ {policy_src_address} ]\n')
75 | if policy_log:
76 | output.write(f'set global policy {policy_name} then log session-close session-init \n')
77 | output.write(f'set global policy {policy_name} then {policy_action} \n\n')
78 | else:
79 | output.write(f'set from-zone {source_zone} to-zone {destination_zone} policy {policy_name} match source-address [ {policy_src_address} ]\n')
80 | output.write(f'set from-zone {source_zone} to-zone {destination_zone} policy {policy_name} match destination-address [ {policy_dst_address} ]\n')
81 | output.write(f'set from-zone {source_zone} to-zone {destination_zone} policy {policy_name} match application [ {policy_app} ]\n')
82 | if policy_log:
83 | output.write(f'set from-zone {source_zone} to-zone {destination_zone} policy {policy_name} then log session-close session-init \n')
84 | output.write(f'set from-zone {source_zone} to-zone {destination_zone} policy {policy_name} then {policy_action}\n\n')
85 |
86 |
--------------------------------------------------------------------------------
/resources/ip_address_converter/netmask_convereter.py:
--------------------------------------------------------------------------------
1 | from ipaddress import IPv4Network
2 |
3 | def netmasker(prefix):
4 | return str(IPv4Network(prefix).network_address) + ' ' + str(IPv4Network(prefix).netmask)
5 |
6 | def nethost(prefix):
7 | return str(IPv4Network(prefix).network_address)
8 |
9 | def sub_mask(prefix):
10 | return str(IPv4Network(prefix).netmask)
11 |
12 | def prefixer(prefix):
13 | return str(IPv4Network(prefix).network_address) + '/' +str(IPv4Network(prefix).prefixlen)
14 |
15 |
16 |
--------------------------------------------------------------------------------
/resources/parser.py:
--------------------------------------------------------------------------------
1 | import os
2 | import logging
3 |
4 | from typing import List
5 |
6 | logger = logging.getLogger('fwmig.parser')
7 |
8 | def main_parser(action: str, cfg: str, src_vendor: str, dst_vendor: str, acts: List[str]) -> bool:
9 | if src_vendor == 'srx':
10 | from resources.src_vendor.srx.srx_config_converter import SRX_Cfg
11 | output = SRX_Cfg(cfg, dst_vendor)
12 | elif src_vendor == 'chpoint':
13 | from resources.src_vendor.chpoint.chpoint_config_parser import CHP_CFG
14 | output = CHP_CFG(cfg, dst_vendor)
15 | elif src_vendor == 'palo':
16 | from resources.src_vendor.palo.palo_config_coverter import PALO_Cfg
17 | output = PALO_Cfg(cfg, dst_vendor)
18 | # elif src_vendor == 'asa':
19 | # from resources.src_vendor.asa.asa_config_converter import ASA_CFG
20 | # output = ASA_CFG(cfg, dst_vendor)
21 |
22 | try:
23 | if action == 'policy':
24 | logger.info('Policy conversion started ...')
25 | output.policy
26 |
27 | elif action == 'config':
28 | output.cleaner
29 | if 'address' in acts:
30 | logger.info('Address and Address_set conversion started ...')
31 | output.address
32 |
33 | if 'service' in acts:
34 | if src_vendor == 'chpoint':
35 | return 'no'
36 | logger.info('Service conversion started ...')
37 | output.service
38 |
39 | if 'service_set' in acts:
40 | if src_vendor == 'chpoint':
41 | return 'no'
42 | logger.info('Service_set conversion started ...')
43 | output.service_set
44 |
45 | # if 'zone' in acts:
46 | # output.zone
47 |
48 | output.delete
49 | logger.info('Conversion finished successfully!')
50 | return True
51 | except Exception as err:
52 | logger.warning('Conversion Failed! Please re-check file content or Source vendor.')
53 | logger.error(err)
54 | logger.info(50*'=')
55 | try:
56 | os.remove(f'configs/{cfg}')
57 | except:
58 | pass
59 | return False
--------------------------------------------------------------------------------
/resources/protocols/nc_conn.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from ncclient import manager
4 | from ncclient import transport
5 |
6 |
7 | logger = logging.getLogger('fwmig.nc')
8 |
9 | class NcMGR:
10 |
11 | def _conn_mgr(self, host: str, username: str, password: str, port: str, device_params: str):
12 | return manager.connect(
13 | host=f'{host}',
14 | username = f'{username}',
15 | password = f'{password}',
16 | port = f'{port}',
17 | hostkey_verify = False,
18 | device_params = {'name': f'{device_params}'}
19 | )
20 |
21 |
22 | # def junos_nc_conn(self, host: str, port: str, device_params: str, ):
23 | def junos_nc_conn(self, action: str, host: str, username: str, password: str, port: str, device_params: str):
24 | if action == 'policy':
25 | action = 'security policies | display xml'
26 | elif action == 'config':
27 | action = 'configuration | display xml'
28 | try:
29 | with self._conn_mgr(host, username, password, port, device_params) as m:
30 | result = m.command(f'show {action}')
31 | except transport.AuthenticationError:
32 | logger.warning(f'Authentication error for {username} on {host}:{port}')
33 | return False
34 | except:
35 | logger.warning('Something went wrong with connection or receiving data.')
36 | return 'other'
37 | with open('configs/nc_fw_result.log', 'w') as f:
38 | logger.info('Writing result to the file ...')
39 | f.write(str(result))
40 | return 'nc_fw_result.log'
--------------------------------------------------------------------------------
/resources/src_vendor/chpoint/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/resources/src_vendor/chpoint/__init__.py
--------------------------------------------------------------------------------
/resources/src_vendor/chpoint/chpoint_config_parser.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import os
3 |
4 | from resources.dst_vendor.dst_forti import Forti_DST
5 | from resources.dst_vendor.dst_asa import ASA_DST
6 | from resources.dst_vendor.dst_palo import Palo_DST
7 | from resources.dst_vendor.dst_srx import SRX_DST
8 | from resources.src_vendor.chpoint.chpoint_policy_parser import chpoint_policy
9 | from resources.ip_address_converter.netmask_convereter import prefixer
10 |
11 |
12 | forti = Forti_DST()
13 | asa = ASA_DST()
14 | palo = Palo_DST()
15 | srx = SRX_DST()
16 |
17 | class CHP_CFG:
18 | def __init__(self, cfg_file: str, vendor: str) -> None:
19 | self.cfg_file = cfg_file
20 | self.vendor = vendor
21 |
22 | @property
23 | def _job(self):
24 | names = ['Name', 'IPv4 address', 'Mask', 'IPv6 address', 'Mask 6', 'Port','Comments']
25 | with open(f'configs/{self.cfg_file}', 'r') as imp_file:
26 | imported = pd.read_csv(imp_file, usecols=names, skiprows=1, names=names, keep_default_na=False, skipinitialspace=True)
27 | parsed = imported[names]
28 | return parsed
29 |
30 | @property
31 | def address(self):
32 | raw_objects = self._job
33 | for _ , row in raw_objects.iterrows():
34 | address_name = row["Name"]
35 | if row["Comments"]:
36 | address_description = row["Comments"]
37 | else:
38 | address_description = ''
39 |
40 | if row["IPv4 address"] and '-' not in row["IPv4 address"]:
41 | ip_address = row["IPv4 address"]
42 |
43 | mask = row["Mask"]
44 | if mask:
45 | address_ip = prefixer(f'{ip_address}/{mask}')
46 | else:
47 | address_ip = prefixer(f'{ip_address}')
48 | # elif row["IPv6 address"]:
49 | # ip_address = row["IPv6 address"]
50 | # mask = row["Mask 6"]
51 | elif '-' in row["IPv4 address"]:
52 | address_ip = row["IPv4 address"]
53 | else:
54 | continue
55 |
56 | if self.vendor == 'forti':
57 | forti.address(address_name, address_ip, address_description)
58 | elif self.vendor == 'asa':
59 | asa.address(address_name, address_ip, address_description)
60 | elif self.vendor == 'palo':
61 | palo.address(address_name, address_ip, address_description)
62 | elif self.vendor == 'srx':
63 | srx.address(address_name, address_ip, address_description)
64 |
65 | @property
66 | def policy(self):
67 | chpoint_policy(self.cfg_file, self.vendor)
68 |
69 | @property
70 | def delete(self):
71 | os.remove(f'configs/{self.cfg_file}')
72 |
73 | @property
74 | def cleaner(self):
75 | if not os.path.exists(f'exported/{self.vendor}'):
76 | os.makedirs(f'exported/{self.vendor}')
77 | else:
78 | for f in os.listdir(f'exported/{self.vendor}/'):
79 | if f != 'policies.txt':
80 | os.remove(os.path.join(f'exported/{self.vendor}/', f))
81 |
82 |
--------------------------------------------------------------------------------
/resources/src_vendor/chpoint/chpoint_policy_parser.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pandas as pd
3 |
4 | from resources.dst_vendor.dst_palo import Palo_DST
5 | from resources.dst_vendor.dst_forti import Forti_DST
6 | from resources.dst_vendor.dst_srx import SRX_DST
7 | from resources.dst_vendor.dst_asa import ASA_DST
8 |
9 | forti_translation = {
10 | 'Accept': 'accept',
11 | 'enabled': 'enable',
12 | 'disabled': 'disable',
13 | 'ftp': 'FTP',
14 | 'tftp': 'TFTP',
15 | 'rtsp': 'RTSP',
16 | 'ssh': 'SSH',
17 | 'telnet': 'TELNET',
18 | 'echo-request': 'PING',
19 | 'ntp-udp': 'NTP',
20 | 'nntp': 'NNTP',
21 | 'http': 'HTTP',
22 | 'https': 'HTTPS',
23 | 'smtp': 'SMTP',
24 | 'syslog': 'SYSLOG',
25 | 'domain-udp': 'DNS',
26 | 'domain-tcp': 'DNS',
27 | 'MS-SQL-Server': 'MS-SQL',
28 | 'smb': 'SMB',
29 | 'nbsession': 'SAMBA',
30 | 'NEW-RADIUS': 'RADIUS',
31 | 'pptp-tcp': 'PPTP',
32 | 'ldap': 'LDAP',
33 | 'ALL_DCE_RPC': 'DCE-RPC',
34 | 'H323': 'H323',
35 | 'ospf': 'OSPF',
36 | 'unknown-protocol-tcp': 'ALL_TCP',
37 | 'unknown-protocol-udp': 'ALL_UDP',
38 | }
39 | palo_translation = {
40 | 'Allow': 'allow',
41 | 'http': 'service-http',
42 | 'https': 'service-https',
43 | }
44 |
45 | srx_translation = {
46 | 'Accept': 'permit',
47 | 'Drop': 'deny',
48 | 'false': 'disabled',
49 | 'true': 'enabled',
50 | 'ftp': 'junos-ftp',
51 | 'tftp': 'junos-tftp',
52 | 'rtsp': 'junos-rtsp',
53 | 'ssh': 'junos-ssh',
54 | 'telnet': 'junos-telnet',
55 | 'echo-request': 'junos-ping',
56 | 'echo-request': 'junos-icmp-ping',
57 | 'ntp-udp': 'junos-ntp',
58 | 'nntp': 'junos-nntp',
59 | 'http': 'junos-http',
60 | 'https': 'junos-https',
61 | 'smtp': 'junos-smtp',
62 | 'syslog': 'junos-syslog',
63 | 'domain-udp': 'junos-dns-udp',
64 | 'domain-tcp': 'junos-dns-tcp',
65 | 'MS-SQL-Server': 'junos-ms-sql',
66 | 'MS-SQL-Monitor_UDP': 'junos-sql-monitor',
67 | 'smb': 'junos-smb-session',
68 | 'nbsession': 'junos-smb',
69 | 'NEW-RADIUS': 'junos-radius',
70 | 'NEW-RADIUS-ACCOUNTING': 'junos-radacct',
71 | 'TACACSplus': 'junos-tacacs',
72 | 'pptp-tcp': 'junos-pptp',
73 | 'ldap': 'junos-ldap',
74 | 'ALL_DCE_RPC': 'junos-ms-rpc-any',
75 | 'who': 'junos-who',
76 | 'CIFS': 'junos-cifs',
77 | 'ospf': 'junos-ospf',
78 | 'unknown_protocol_tcp': 'junos-tcp-any',
79 | 'unknown_protocol_udp': 'junos-udp-any',
80 | }
81 |
82 | asa_translation = {
83 | 'Accept': 'permit',
84 | 'disabled': 'inactive',
85 | 'ftp': ['tcp', 'ftp'],
86 | 'tftp': ['udp', 'tftp'],
87 | 'rtsp': ['tcp', 'rtsp'],
88 | 'ssh': ['tcp', 'ssh'],
89 | 'telnet': ['tcp', 'telnet'],
90 | 'echo-request': ['icmp', 'na'],
91 | 'ntp': ['udp', 'ntp'],
92 | 'nntp': ['tcp','nntp'],
93 | 'http': ['tcp', 'http'],
94 | 'https': ['tcp', 'https'],
95 | 'smtp': ['tcp', 'smtp'],
96 | 'syslog': ['udp', 'syslog'],
97 | 'echo-request': ['icmp', 'echo'],
98 | 'domain-udp': ['udp', 'domain'],
99 | 'domain-tcp': ['tcp', 'domain'],
100 | 'smb': ['tcp', 'netbios-ssn'],
101 | 'NEW-RADIUS': ['udp', 'radius'],
102 | 'NEW-RADIUS-ACCOUNTING': ['udp', 'radius-acct'],
103 | 'TACACSplus': ['tcp', 'tacacs'],
104 | 'pptp-tcp': ['tcp', 'pptp'],
105 | 'ldap': ['tcp', 'ldap'],
106 | 'who': ['udp', 'who'],
107 | 'CIFS': ['tcp-udp', 'cifs'],
108 | 'ospf': ['ospf', 'na'],
109 | 'unknown_protocol_tcp': ['tcp', 'na'],
110 | 'unknown_protocol_udp': ['udp', 'na'],
111 | }
112 |
113 | def chpoint_policy(file: str, vendor: str):
114 | """Uses to provide rule order!"""
115 | if not os.path.exists(f'exported/{vendor}'):
116 | os.makedirs(f'exported/{vendor}')
117 | else:
118 | try:
119 | os.remove(os.path.join(f'exported/{vendor}/', 'policies.txt'))
120 | except:
121 | pass
122 |
123 | names = ["No.", "Name", "Source", "Destination", "Services & Applications", "Action", "Track"]
124 | cols = [0, 2, 3, 4, 6, 8, 9]
125 | with open(f'configs/{file}', 'r') as f:
126 | imported = pd.read_csv(f, usecols=cols, names=names, skiprows=1, keep_default_na=False, skipinitialspace=True)
127 | os.remove(f'configs/{file}')
128 |
129 | for _, row in imported.iterrows():
130 | policy_id = row["No."]
131 | policy_name = row["Name"]
132 | policy_src_address = row["Source"]
133 | policy_dst_address = row["Destination"]
134 | policy_action = row["Action"]
135 | policy_log = row["Track"]
136 | policy_app = row["Services & Applications"]
137 | source_zone = 'global'
138 | destination_zone = 'global'
139 | policy_state = ''
140 |
141 | try:
142 | app_list = policy_app.split(';')
143 | new_list = []
144 | for app in app_list:
145 | if vendor == 'forti':
146 | policy_app = forti_translation.get(app, app)
147 | elif vendor == 'palo':
148 | policy_app = palo_translation.get(app, app)
149 | elif vendor == 'srx':
150 | policy_app = srx_translation.get(app, app)
151 | elif vendor == 'asa':
152 | policy_app = asa_translation.get(app, app)
153 | new_list.append(policy_app)
154 | policy_app = ' '.join(new_list)
155 | except:
156 | pass
157 | try:
158 | src_list = policy_src_address.split(';')
159 | policy_src_address = ' '.join(src_list)
160 | except:
161 | pass
162 |
163 | try:
164 | dst_list = policy_dst_address.split(';')
165 | policy_dst_address = ' '.join(dst_list)
166 | except:
167 | pass
168 |
169 | if vendor == 'forti':
170 | policy_action = forti_translation.get(policy_action, policy_action)
171 | if 'Any' in policy_src_address:
172 | policy_src_address = 'all'
173 | if 'Any' in policy_dst_address:
174 | policy_dst_address == 'all'
175 | if policy_app == 'Any':
176 | policy_app = 'ALL'
177 |
178 | forti = Forti_DST()
179 | forti.policy(
180 | policy_name,
181 | source_zone,
182 | destination_zone,
183 | policy_src_address,
184 | policy_dst_address,
185 | policy_app,
186 | policy_log,
187 | policy_state,
188 | policy_action,
189 | policy_id
190 | )
191 |
192 | elif vendor == 'asa':
193 | policy_action = asa_translation.get(policy_action, policy_action)
194 | if 'Any' in policy_src_address:
195 | policy_src_address = 'any'
196 | if 'Any' in policy_dst_address:
197 | policy_dst_address == 'any'
198 | if policy_app == 'Any':
199 | policy_app = 'any'
200 | asa = ASA_DST()
201 | asa.policy(
202 | policy_name,
203 | source_zone,
204 | destination_zone,
205 | policy_src_address,
206 | policy_dst_address,
207 | policy_app,
208 | policy_log,
209 | policy_state,
210 | policy_action,
211 | policy_id
212 | )
213 | elif vendor == 'palo':
214 | policy_action = palo_translation.get(policy_action, policy_action)
215 | palo = Palo_DST()
216 | palo.policy(
217 | policy_name,
218 | source_zone,
219 | destination_zone,
220 | policy_src_address,
221 | policy_dst_address,
222 | policy_app,
223 | policy_log,
224 | policy_state,
225 | policy_action
226 | )
227 | elif vendor == 'srx':
228 | policy_action = srx_translation.get(policy_action, policy_action)
229 | if 'Any' in policy_src_address:
230 | policy_src_address = 'any'
231 | if 'Any' in policy_dst_address:
232 | policy_dst_address == 'any'
233 | if policy_app == 'Any':
234 | policy_app = 'any'
235 | srx = SRX_DST()
236 | srx.policy(
237 | policy_name,
238 | source_zone,
239 | destination_zone,
240 | policy_src_address,
241 | policy_dst_address,
242 | policy_app,
243 | policy_log,
244 | policy_state,
245 | policy_action
246 | )
247 |
--------------------------------------------------------------------------------
/resources/src_vendor/palo/palo_config_coverter.py:
--------------------------------------------------------------------------------
1 | import json
2 | import xmltodict
3 | import os
4 | import logging
5 |
6 |
7 | from resources.dst_vendor.dst_srx import SRX_DST
8 | from resources.dst_vendor.dst_forti import Forti_DST
9 | from resources.dst_vendor.dst_asa import ASA_DST
10 | from resources.dst_vendor.dst_chpoint import CHPoint_DST
11 | from resources.src_vendor.palo.palo_policy_convert import palo_policy
12 | from ipaddress import ip_network
13 |
14 | srx = SRX_DST()
15 | forti = Forti_DST()
16 | asa = ASA_DST()
17 | chpoint = CHPoint_DST()
18 | logger = logging.getLogger('fwmig.palo.config')
19 |
20 |
21 | class PALO_Cfg:
22 | """Converts PA -> Fortigate, ASA, Forti, Palo Alto (except zone and interfaces) """
23 | def __init__(self, cfg_file: str, vendor: str) -> None:
24 | self.cfg_file = cfg_file
25 | self.vendor = vendor
26 |
27 | @property
28 | def _job(self):
29 | with open(f'configs/{self.cfg_file}', 'r') as imp_file:
30 | xml_dict = xmltodict.parse(imp_file.read())
31 | json_formatted = json.dumps(xml_dict)
32 | dict_formatted = json.loads(json_formatted)
33 | try:
34 | return dict_formatted['root']['response']
35 | except:
36 | logger.error(' or are not exists on the config. Conversion failed!')
37 | return False
38 |
39 | @property
40 | def service(self):
41 | """Exports custom application created on PaloAlto"""
42 | logger.info('Service process started ...')
43 |
44 | dict_formatted = self._job
45 | if not dict_formatted:
46 | return False
47 | for i in range(len(dict_formatted)):
48 | try:
49 | if 'service' in dict_formatted[i]['result']:
50 | applications_list = dict_formatted[i]['result']['service']['entry']
51 | except:
52 | continue
53 |
54 | for index in range(len(applications_list)):
55 | application_name = applications_list[index].get('@name', 'None')
56 | application_desc = applications_list[index].get('description')
57 | application_protocol = applications_list[index]['protocol'].keys()
58 | application_protocol = list(application_protocol)[0]
59 | destination_port = applications_list[index]['protocol'][application_protocol]['port']
60 | source_port = ''
61 | session_ttl = ''
62 |
63 |
64 | if self.vendor == 'forti':
65 | forti.service(application_name, destination_port, source_port, application_protocol, application_desc, session_ttl)
66 | elif self.vendor == 'asa':
67 | asa.service(application_name, destination_port, source_port, application_protocol, application_desc)
68 |
69 | elif self.vendor == 'srx':
70 | srx.service(application_name, destination_port, source_port, application_protocol, application_desc, session_ttl)
71 |
72 | elif self.vendor == 'chpoint':
73 | if not source_port:
74 | source_port = ''
75 | # Because the platform does not support name start with Digits!
76 | if application_name[:1].isdigit():
77 | application_name = 'custom_' + application_name
78 | if "," in destination_port:
79 | # instead of skipping, creating single services and than a group would make more sense in the future
80 | logger.warn(f"Skipping Service {application_name} since it has multiple ports set, which checkpoint can't handle. Please add it manually afterwards")
81 | continue
82 | chpoint.service(application_name, destination_port, source_port, application_protocol, application_desc, session_ttl)
83 |
84 |
85 |
86 | @property
87 | def service_set(self):
88 | """Exports custome application-set created on SRX"""
89 | logger.info('Service-set process started ...')
90 |
91 | dict_formatted = self._job
92 | if not dict_formatted:
93 | return False
94 |
95 | for i in range(len(dict_formatted)):
96 | try:
97 | if 'service-group' in dict_formatted[i]['result']:
98 | applications_list = dict_formatted[i]['result']['service-group']['entry']
99 | logger.info('Service-group exists in policy')
100 | except:
101 | logger.info('Service-group is not in policy')
102 | continue
103 | if not isinstance(applications_list,list):
104 | # if only one applications_list exists
105 | applications_list = [applications_list]
106 | for index in range(len(applications_list)):
107 | app_list = []
108 | app_set_name = applications_list[index].get('@name', 'None')
109 | app_set_desc = applications_list[index].get('description')
110 | app_set_main = applications_list[index]['members']['member']
111 | for sub_index in range(len(app_set_main)):
112 | app_name = app_set_main[sub_index]
113 |
114 |
115 | app_list.append(app_name)
116 | if not self.vendor == 'asa':
117 | app_name = ' '.join(app_list)
118 |
119 | if self.vendor == 'forti':
120 | forti.service_set(app_set_name, app_name, app_set_desc)
121 | elif self.vendor == 'asa':
122 | asa.service_set(app_set_name, app_list, app_set_desc)
123 | elif self.vendor == 'srx':
124 | srx.service_set(app_set_name, app_name)
125 | elif self.vendor == 'chpoint':
126 | chpoint.service_set(app_set_name, app_list, app_set_desc)
127 |
128 |
129 | @property
130 | def address(self):
131 | """Converts address books"""
132 | logger.info('Address and address-group process started ...')
133 |
134 | dict_formatted = self._job
135 | if not dict_formatted:
136 | return False
137 |
138 | for i in range(len(dict_formatted)):
139 | try:
140 | if 'address' in dict_formatted[i]['result']:
141 | address_list = dict_formatted[i]['result']['address']['entry']
142 | elif 'address-group' in dict_formatted[i]['result']:
143 | address_set_books = dict_formatted[i]['result']['address-group']['entry']
144 | except:
145 | logger.info('Address-group or address is not in policy')
146 | continue
147 |
148 | for index in range(len(address_list)):
149 | address_name = address_list[index].get('@name', 'None')
150 | address_description = address_list[index].get('description')
151 | address_ip = address_list[index].get('ip-netmask', 'None')
152 | if address_ip == 'None' or address_name == 'None':
153 | continue
154 |
155 |
156 | if self.vendor == 'forti':
157 | forti.address(address_name, address_ip, address_description)
158 |
159 | elif self.vendor == 'asa':
160 | asa.address(address_name, address_ip, address_description)
161 |
162 | elif self.vendor == 'srx':
163 | srx.address(address_name, address_ip, address_description)
164 |
165 | elif self.vendor == 'chpoint':
166 | if "/" not in address_ip:
167 | address_ip = address_ip+"/32"
168 | try:
169 | ip_network(address_ip, strict=True)
170 | # address_ip is a valid network address (or a valid host with /32 mask) -->nothing to do
171 | except ValueError:
172 | # address_ip is a palo specific host address that also has a network mask
173 | # --> convert to Host
174 | address_ip = address_ip.split("/")[0]+"/32"
175 | chpoint.address(address_name, address_ip, address_description)
176 |
177 |
178 |
179 | if address_set_books:
180 | if not isinstance(address_set_books,list):
181 | # if only one address-group exists
182 | address_set_books = [address_set_books]
183 | for index in range(len(address_set_books)):
184 | address_name_list = []
185 | address_set_name = address_set_books[index].get('@name', 'None')
186 | address_set_desc = address_set_books[index].get('description')
187 |
188 | address_set_main = address_set_books[index]['static']['member']
189 | for sub_index in range(len(address_set_main)):
190 | address_name = address_set_main[sub_index]
191 | address_name_list.append(address_name)
192 | address_name = ' '.join(address_name_list)
193 |
194 | if self.vendor == 'forti':
195 | forti.address_set(address_set_name, address_name, address_set_desc)
196 | elif self.vendor == 'asa':
197 | asa.address_set(address_set_name, address_name_list, address_set_desc)
198 | elif self.vendor == 'srx':
199 | srx.address_set(address_set_name, address_name, address_set_desc)
200 | elif self.vendor == 'chpoint':
201 | chpoint.address_set(address_set_name, address_name_list, address_set_desc)
202 |
203 | @property
204 | def policy(self):
205 | logger.info('Policy process started ...')
206 | palo_policy(self.cfg_file, self.vendor)
207 |
208 | @property
209 | def delete(self):
210 | os.remove(f'configs/{self.cfg_file}')
211 |
212 | @property
213 | def cleaner(self):
214 | if not os.path.exists(f'exported/{self.vendor}'):
215 | os.makedirs(f'exported/{self.vendor}')
216 | else:
217 | for f in os.listdir(f'exported/{self.vendor}/'):
218 | if f != 'policies.txt':
219 | os.remove(os.path.join(f'exported/{self.vendor}/', f))
220 |
221 |
--------------------------------------------------------------------------------
/resources/src_vendor/palo/palo_policy_convert.py:
--------------------------------------------------------------------------------
1 | import xmltodict
2 | import json
3 | import os
4 | import logging
5 |
6 | from resources.dst_vendor.dst_srx import SRX_DST
7 | from resources.dst_vendor.dst_forti import Forti_DST
8 | from resources.dst_vendor.dst_chpoint import CHPoint_DST
9 | from resources.dst_vendor.dst_asa import ASA_DST
10 |
11 | forti_translation = {
12 | 'allow': 'accept',
13 | 'no': 'enable',
14 | 'yes': 'disable',
15 | 'service-http': 'HTTP',
16 | 'service-https': 'HTTPS',
17 | }
18 | srx_translation = {
19 | 'allow': 'permit',
20 | 'no': 'enabled',
21 | 'yes': 'disabled',
22 | 'service-http': 'junos-http',
23 | 'service-https': 'junos-https',
24 | }
25 |
26 | chpoint_translation = {
27 | 'allow': 'accept',
28 | 'deny': 'drop',
29 | 'yes': 'false',
30 | 'no': 'true',
31 | 'service-http': 'http',
32 | 'service-https': 'https',
33 | }
34 |
35 | asa_translation = {
36 | 'yes': 'inactive',
37 | 'service-http': ['tcp', 'http'],
38 | 'service-https': ['tcp', 'https'],
39 | }
40 |
41 | logger = logging.getLogger('fwmig.palo.policy')
42 |
43 | def palo_policy(file: str, vendor: str):
44 | """Uses to provide rule order!"""
45 | if not os.path.exists(f'exported/{vendor}'):
46 | os.makedirs(f'exported/{vendor}')
47 | else:
48 | try:
49 | os.remove(os.path.join(f'exported/{vendor}/', 'policies.txt'))
50 | except:
51 | pass
52 |
53 | try:
54 | with open(f'configs/{file}', 'r') as f:
55 | my_text = xmltodict.parse(f.read())
56 | except Exception as err:
57 | logger.error(f'Check file format. Maybe tag is not exists!')
58 | raise ValueError(err)
59 |
60 | os.remove(f'configs/{file}')
61 |
62 | try:
63 | json_formatted = json.dumps(my_text)
64 | dict_formatted = json.loads(json_formatted)['root']['response']
65 | except:
66 | logger.error(' or are not exists on the config. Conversion failed!')
67 |
68 | for i in range(len(dict_formatted)):
69 | try:
70 | if 'rulebase' in dict_formatted[i]['result']:
71 | security_cfg = dict_formatted[i]['result']['rulebase']['security']['rules']['entry']
72 | except:
73 | continue
74 | position = 1
75 |
76 | try:
77 | len(security_cfg)
78 | except:
79 | raise ValueError("This tool can't work for one rule!")
80 |
81 | for main_index in range(len(security_cfg)):
82 | policy_src_list = []
83 | policy_dst_list = []
84 | policy_app_list = []
85 |
86 | policy_name = security_cfg[main_index]['@name']
87 | source_zone = security_cfg[main_index]['from']['member']
88 | destination_zone = security_cfg[main_index]['to']['member']
89 | source_address_list = security_cfg[main_index]['source']['member']
90 | destination_address_list = security_cfg[main_index]['destination']['member']
91 | service_address_list = security_cfg[main_index]['service']['member']
92 | # application_address_list = security_cfg[main_index]['application']
93 | try:
94 | policy_state = security_cfg[main_index]['disabled']
95 | except:
96 | policy_state = 'no'
97 | policy_action = security_cfg[main_index]['action']
98 | try:
99 | policy_log = security_cfg[main_index]['log-start']
100 | except:
101 | policy_log = False
102 | policy_id = position
103 |
104 | if isinstance(source_address_list, (list)):
105 | for sub_index in range(len(source_address_list)):
106 | policy_src_address = source_address_list[sub_index]
107 | policy_src_list.append(policy_src_address)
108 | else:
109 | policy_src_address = source_address_list
110 |
111 | if isinstance(destination_address_list, (list)):
112 | for sub_index in range(len(destination_address_list)):
113 | policy_dst_address = destination_address_list[sub_index]
114 | policy_dst_list.append(policy_dst_address)
115 | else:
116 | policy_dst_address = destination_address_list
117 |
118 | if isinstance(service_address_list, (list)):
119 | for sub_index in range(len(service_address_list)):
120 | policy_app = service_address_list[sub_index]
121 | policy_app_list.append(policy_app)
122 | else:
123 | policy_app = service_address_list
124 |
125 | if policy_log:
126 | policy_log = True
127 | else:
128 | policy_log = False
129 | if policy_src_list:
130 | policy_src_address = ' '.join(policy_src_list)
131 | if policy_dst_list:
132 | policy_dst_address = ' '.join(policy_dst_list)
133 | if policy_app_list:
134 | try:
135 | policy_app = ' '.join(policy_app_list)
136 | except:
137 | policy_app = policy_app_list
138 |
139 | if vendor == 'forti':
140 | policy_state = forti_translation.get(policy_state, policy_state)
141 | policy_action = forti_translation.get(policy_action, policy_action)
142 | if 'any' in policy_src_address:
143 | policy_src_address = 'all'
144 | if 'any' in policy_dst_address:
145 | policy_dst_address = 'all'
146 | if policy_app == 'any':
147 | policy_app = 'ALL'
148 | if len(policy_name) > 34:
149 | policy_name = policy_name[:34]
150 |
151 | forti = Forti_DST()
152 | forti.policy(
153 | policy_name,
154 | source_zone,
155 | destination_zone,
156 | policy_src_address,
157 | policy_dst_address,
158 | policy_app,
159 | policy_log,
160 | policy_state,
161 | policy_action,
162 | policy_id
163 | )
164 |
165 | elif vendor == 'asa':
166 | policy_action = asa_translation.get(policy_action, policy_action)
167 | asa = ASA_DST()
168 | asa.policy(
169 | policy_name,
170 | source_zone,
171 | destination_zone,
172 | policy_src_address,
173 | policy_dst_address,
174 | policy_app,
175 | policy_log,
176 | policy_state,
177 | policy_action,
178 | policy_id
179 | )
180 | elif vendor == 'srx':
181 | policy_action = srx_translation.get(policy_action, policy_action)
182 | srx = SRX_DST()
183 | srx.policy(
184 | policy_name,
185 | source_zone,
186 | destination_zone,
187 | policy_src_address,
188 | policy_dst_address,
189 | policy_app,
190 | policy_log,
191 | policy_state,
192 | policy_action
193 | )
194 |
195 | elif vendor == 'chpoint':
196 | policy_action = chpoint_translation.get(policy_action, policy_action)
197 | policy_state = chpoint_translation.get(policy_state, policy_state)
198 |
199 | if policy_dst_list:
200 | dst_list = []
201 | for i in range(len(policy_dst_list)):
202 | dst_list.append(f'destination.{i+1} "{policy_dst_list[i]}"')
203 | policy_dst_address = ' '.join(dst_list)
204 | else:
205 | policy_dst_address = f'destination "{"Any" if str(policy_dst_address).strip().lower() == "any" else policy_dst_address}"' #checkpoint need to have "Any" as string not "any" (Case is important)
206 |
207 | if policy_src_list:
208 | src_list = []
209 | for i in range(len(policy_src_list)):
210 | src_list.append(f'source.{i+1} "{policy_src_list[i]}"')
211 | policy_src_address = ' '.join(src_list)
212 | else:
213 | policy_src_address = f'source "{"Any" if str(policy_src_address).strip().lower() == "any" else policy_src_address}"' #checkpoint need to have "Any" as string not "any" (Case is important)
214 | if policy_app_list:
215 | app_list = []
216 | for i in range(len(policy_app_list)):
217 | if policy_app_list[i][:1].isdigit():
218 | policy_app = 'custom_' + policy_app_list[i]
219 | else:
220 | policy_app = policy_app_list[i]
221 | app_list.append(f'service.{i+1} "{policy_app}"')
222 | policy_app = ' '.join(app_list)
223 | else:
224 | if policy_app[:1].isdigit():
225 | policy_app = 'custom_' + policy_app
226 | elif str(policy_app).strip().lower() == "any" :
227 | policy_app = "Any" #checkpoint need to have "Any" as string not "any" (Case is important)
228 | elif str(policy_app).strip().lower() == "application-default":
229 | policy_app = "Any" #application-default concept does not exist in checkpoint (see https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClVwCAK)
230 | policy_app = f'service {policy_app}'
231 |
232 |
233 | chpoint = CHPoint_DST()
234 | chpoint.policy(
235 | policy_name,
236 | source_zone,
237 | destination_zone,
238 | policy_src_address,
239 | policy_dst_address,
240 | policy_app,
241 | policy_log,
242 | policy_state,
243 | policy_action,
244 | policy_id,
245 | position
246 | )
247 |
248 |
249 | position += 1
250 |
--------------------------------------------------------------------------------
/resources/src_vendor/srx/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VahidTa/firewall_migration_tool/06f0ff0d0714f9563fe21b83d69711e66a8f0b1c/resources/src_vendor/srx/__init__.py
--------------------------------------------------------------------------------
/resources/src_vendor/srx/srx_config_converter.py:
--------------------------------------------------------------------------------
1 | import json
2 | import xmltodict
3 | import os
4 | import logging
5 |
6 | from resources.src_vendor.srx.srx_policy_convert import forti_translation,\
7 | palo_translation,\
8 | chpoint_translation,\
9 | asa_translation
10 |
11 | from resources.dst_vendor.dst_palo import Palo_DST
12 | from resources.dst_vendor.dst_forti import Forti_DST
13 | from resources.dst_vendor.dst_asa import ASA_DST
14 | from resources.dst_vendor.dst_chpoint import CHPoint_DST
15 | from resources.src_vendor.srx.srx_policy_convert import srx_policy
16 |
17 |
18 |
19 | palo = Palo_DST()
20 | forti = Forti_DST()
21 | asa = ASA_DST()
22 | chpoint = CHPoint_DST()
23 | logger = logging.getLogger('fwmig.srx.config')
24 |
25 | class SRX_Cfg:
26 | """Converts SRX -> Fortigate, ASA, Forti, Palo Alto (except zone and interfaces) """
27 | def __init__(self, cfg_file: str, vendor: str) -> None:
28 | self.cfg_file = cfg_file
29 | self.vendor = vendor
30 |
31 | @property
32 | def _job(self):
33 | with open(f'configs/{self.cfg_file}', 'r') as imp_file:
34 | xml_dict = xmltodict.parse(imp_file.read())
35 | json_formatted = json.dumps(xml_dict)
36 | dict_formatted = json.loads(json_formatted)
37 | return dict_formatted['rpc-reply']['configuration']
38 |
39 | @property
40 | def service(self):
41 | """Exports custom application created on SRX"""
42 |
43 | dict_formatted = self._job
44 |
45 | applications_list = dict_formatted['applications']
46 | apps= applications_list['application']
47 |
48 | for index in range(len(apps)):
49 | application_name = apps[index].get('name', 'None')
50 | application_desc = apps[index].get('description')
51 | application_protocol = apps[index].get('protocol', 'None')
52 | destination_port = apps[index].get('destination-port')
53 | source_port = apps[index].get('source-port')
54 | session_ttl = apps[index].get('inactivity-timeout')
55 |
56 | if self.vendor == 'forti':
57 | forti.service(application_name, destination_port, source_port, application_protocol, application_desc, session_ttl)
58 | elif self.vendor == 'asa':
59 | asa.service(application_name, destination_port, source_port, application_protocol, application_desc)
60 |
61 | elif self.vendor == 'palo':
62 | if session_ttl == 'never':
63 | session_ttl = False
64 | palo.service(application_name, destination_port, source_port, application_protocol, application_desc, session_ttl)
65 |
66 | elif self.vendor == 'chpoint':
67 | if not source_port:
68 | source_port = ''
69 | if (not session_ttl) or (session_ttl == 'never'):
70 | session_ttl = ''
71 | # Because the platform does not support name start with Digits!
72 | if application_name[:1].isdigit():
73 | application_name = 'custom_' + application_name
74 |
75 | chpoint.service(application_name, destination_port, source_port, application_protocol, application_desc, session_ttl)
76 |
77 |
78 |
79 | @property
80 | def service_set(self):
81 | """Exports custome application-set created on SRX"""
82 |
83 | dict_formatted = self._job
84 |
85 | applications_list = dict_formatted['applications']
86 | apps_set = applications_list['application-set']
87 |
88 | for index in range(len(apps_set)):
89 | app_list = []
90 | app_set_name = apps_set[index].get('name', 'None')
91 | app_set_desc = apps_set[index].get('description')
92 | app_set_main = apps_set[index]['application']
93 | for sub_index in range(len(app_set_main)):
94 | app_name = app_set_main[sub_index].get('name', 'None')
95 |
96 | if self.vendor == 'forti' and 'junos' in app_name:
97 | app_name = forti_translation.get(app_name, app_name)
98 | elif self.vendor == 'palo' and 'junos' in app_name:
99 | app_name = palo_translation.get(app_name, app_name)
100 | elif self.vendor == 'chpoint' and 'junos' in app_name:
101 | app_name = chpoint_translation.get(app_name, app_name)
102 | elif self.vendor == 'asa' and 'junos' in app_name:
103 | app_name = asa_translation.get(app_name, app_name)
104 |
105 | app_list.append(app_name)
106 | if not self.vendor == 'asa':
107 | app_name = ' '.join(app_list)
108 |
109 | if self.vendor == 'forti':
110 | forti.service_set(app_set_name, app_name, app_set_desc)
111 | elif self.vendor == 'asa':
112 | asa.service_set(app_set_name, app_list, app_set_desc)
113 | elif self.vendor == 'palo':
114 | palo.service_set(app_set_name, app_name)
115 | elif self.vendor == 'chpoint':
116 | chpoint.address_set(app_set_name, app_list, app_set_desc)
117 |
118 |
119 | @property
120 | def address(self):
121 | """Converts address books"""
122 |
123 | security_cfg = self._job
124 | try:
125 | address_books = security_cfg['security']['address-book']['address']
126 | address_set_books = security_cfg['security']['address-book']['address-set']
127 | check = True
128 | except:
129 | address_books = security_cfg['security']['zones']['security-zone']
130 | address_set_books = security_cfg['security']['zones']['security-zone']
131 | check = False
132 |
133 | for index in range(len(address_books)):
134 | address_list = []
135 | if check:
136 | address_name = address_books[index].get('name', 'None')
137 | address_description = address_books[index].get('description')
138 | address_ip = address_books[index].get('ip-prefix', 'None')
139 | else:
140 | try:
141 | address_b = address_books[index]['address-book']['address']
142 | except:
143 | continue
144 | for sub_index in range(len(address_b)):
145 | if isinstance(address_b, (list)):
146 | address_name = address_b[sub_index].get('name', 'None')
147 | address_description = address_b[sub_index].get('description')
148 | address_ip = address_b[sub_index].get('ip-prefix', 'None')
149 | address_list.append([address_name, address_description, address_ip])
150 | else:
151 | address_name = address_b.get('name', 'None')
152 | address_description = address_b.get('description')
153 | address_ip = address_b.get('ip-prefix', 'None')
154 |
155 |
156 | if self.vendor == 'forti':
157 | if address_list:
158 | for i in range(len(address_list)):
159 | address_name = address_list[i][0]
160 | address_description = address_list[i][1]
161 | address_ip = address_list[i][2]
162 | forti.address(address_name, address_ip, address_description)
163 | else:
164 | forti.address(address_name, address_ip, address_description)
165 |
166 | elif self.vendor == 'asa':
167 | if address_list:
168 | for i in range(len(address_list)):
169 | address_name = address_list[i][0]
170 | address_description = address_list[i][1]
171 | address_ip = address_list[i][2]
172 | asa.address(address_name, address_ip, address_description)
173 | else:
174 | asa.address(address_name, address_ip, address_description)
175 |
176 | elif self.vendor == 'palo':
177 | if address_list:
178 | for i in range(len(address_list)):
179 | address_name = address_list[i][0]
180 | address_description = address_list[i][1]
181 | address_ip = address_list[i][2]
182 | palo.address(address_name, address_ip, address_description)
183 | else:
184 | palo.address(address_name, address_ip, address_description)
185 |
186 | elif self.vendor == 'chpoint':
187 | if address_list:
188 | for i in range(len(address_list)):
189 | address_name = address_list[i][0]
190 | address_description = address_list[i][1]
191 | address_ip = address_list[i][2]
192 | chpoint.address(address_name, address_ip, address_description)
193 | else:
194 | chpoint.address(address_name, address_ip, address_description)
195 |
196 |
197 |
198 | if address_set_books:
199 | for index in range(len(address_set_books)):
200 | address_name_list = []
201 | if not check:
202 | try:
203 | address_b = address_set_books[index]['address-book']['address-set']
204 | except:
205 | continue
206 | address_set_name = address_b.get('name', 'None')
207 | address_set_desc = address_b.get('description')
208 | address_set_main = address_b.get('address', 'None')
209 | else:
210 | address_set_name = address_set_books[index].get('name', 'None')
211 | address_set_desc = address_set_books[index].get('description')
212 | address_set_main = address_set_books[index].get('address', 'None')
213 | for sub_index in range(len(address_set_main)):
214 | address_name = address_set_main[sub_index].get('name', 'None')
215 | address_name_list.append(address_name)
216 | address_name = ' '.join(address_name_list)
217 |
218 | if self.vendor == 'forti':
219 | forti.address_set(address_set_name, address_name, address_set_desc)
220 | elif self.vendor == 'asa':
221 | asa.address_set(address_set_name, address_name_list, address_set_desc)
222 | elif self.vendor == 'palo':
223 | palo.address_set(address_set_name, address_name, address_set_desc)
224 | elif self.vendor == 'chpoint':
225 | chpoint.address_set(address_set_name, address_name_list, address_set_desc)
226 |
227 | @property
228 | def policy(self):
229 | srx_policy(self.cfg_file, self.vendor)
230 |
231 | @property
232 | def zone(self):
233 | """Not Implemented"""
234 | return
235 | # item = SRX_Int('test', '10.10.10.10/24')
236 | # item.save_to_db()
237 |
238 | security_cfg = self._job
239 | # zones = security_cfg['security']['zones']['security-zone']
240 |
241 | # for main_index in range(len(zones)):
242 | # service_list = []
243 | # zone_int_list = []
244 |
245 | # zone_name = zones[main_index].get('name', 'None')
246 | # zone_service = zones[main_index]['host-inbound-traffic']['system-services']
247 | # zone_ints = zones[main_index]['interfaces']
248 | # if isinstance(zone_service, (list)):
249 | # for sub_index in range(len(zone_service)):
250 | # service = zone_service[sub_index].get('name', 'None')
251 | # service_list.append(service)
252 | # else:
253 | # service = zone_service.get('name', 'None')
254 | # service_list.append(service)
255 | # service = ' '.join(service_list)
256 |
257 | # if isinstance(zone_ints, (list)):
258 | # for sub_index in range(len(zone_ints)):
259 | # zone_int = zone_ints[sub_index].get('name', 'None')
260 | # zone_int_list.append(zone_int)
261 | # else:
262 | # zone_int = zone_ints.get('name', 'None')
263 | # zone_int_list.append(zone_int)
264 | # zone_int = ' '.join(zone_int_list)
265 | # if self.vendor == 'forti':
266 | # with open('exported/forti/zones.txt', 'a') as f:
267 | # f.write(f'zone {zone_name} ')
268 |
269 |
270 | interfaces = security_cfg['interfaces']['interface']
271 |
272 | for main_index in range(len(interfaces)):
273 | # name_list = []
274 | # vlan_list = []
275 | # ip_list = []
276 | int_name = interfaces[main_index].get('name')
277 | int_units = interfaces[main_index].get('unit')
278 |
279 | if int_units:
280 | if isinstance(int_units, (list)):
281 | for sub_index in range(len(int_units)):
282 | unit_name = int_units[sub_index].get('name')
283 | # name_list.append(unit_name)
284 | vlan_id = int_units[sub_index].get('vlan-id')
285 | # vlan_list.append(vlan_id)
286 | try:
287 | ip_addr = int_units[sub_index]['family']['inet']['address'].get('name', 'None')
288 | # ip_list.append(ip_addr)
289 | print(int_name+'.'+unit_name, vlan_id)
290 | item = SRX_Int(int_name+'.'+unit_name, vlan_id, ip_addr)
291 | logger.info(f'{item} created!')
292 | item.save_to_db()
293 | except:
294 | pass
295 |
296 | else:
297 | unit_name = int_units.get('name')
298 | vlan_id = int_units.get('vlan-id')
299 | try:
300 | ip_addr = int_units['family']['inet']['address'].get('name', 'None')
301 | item = SRX_Int(int_name+'.'+unit_name, vlan_id, ip_addr)
302 | logger.info(f'{item} created!')
303 | item.save_to_db()
304 | except:
305 | pass
306 | test = SRX_Int.findby_interface('10')
307 | print(test)
308 |
309 | # with open('exported/vahid.txt', 'a') as f:
310 | # f.write(test)
311 | # unit_name = ' '.join(name_list)
312 | # if vlan_list:
313 | # vlan_id = ' '.join(vlan_list)
314 | # else:
315 | # vlan_id = 0
316 | # if ip_list:
317 | # ip_addr = ' '.join(ip_list)
318 | # else:
319 | # ip_addr = "n/a"
320 |
321 |
322 | # print(int_name, unit_name, ip_addr)
323 |
324 | @property
325 | def delete(self):
326 | os.remove(f'configs/{self.cfg_file}')
327 |
328 | @property
329 | def cleaner(self):
330 | if not os.path.exists(f'exported/{self.vendor}'):
331 | os.makedirs(f'exported/{self.vendor}')
332 | else:
333 | for f in os.listdir(f'exported/{self.vendor}/'):
334 | if f != 'policies.txt':
335 | os.remove(os.path.join(f'exported/{self.vendor}/', f))
336 |
--------------------------------------------------------------------------------
/resources/src_vendor/srx/srx_policy_convert.py:
--------------------------------------------------------------------------------
1 | import xmltodict
2 | import json
3 | import os
4 |
5 | from resources.dst_vendor.dst_palo import Palo_DST
6 | from resources.dst_vendor.dst_forti import Forti_DST
7 | from resources.dst_vendor.dst_chpoint import CHPoint_DST
8 | from resources.dst_vendor.dst_asa import ASA_DST
9 |
10 | forti_translation = {
11 | 'permit': 'accept',
12 | 'enabled': 'enable',
13 | 'disabled': 'disable',
14 | 'junos-ftp': 'FTP',
15 | 'junos-tftp': 'TFTP',
16 | 'junos-rtsp': 'RTSP',
17 | 'junos-ssh': 'SSH',
18 | 'junos-telnet': 'TELNET',
19 | 'junos-ping': 'PING',
20 | 'junos-ntp': 'NTP',
21 | 'junos-nntp': 'NNTP',
22 | 'junos-http': 'HTTP',
23 | 'junos-https': 'HTTPS',
24 | 'junos-smtp': 'SMTP',
25 | 'junos-syslog': 'SYSLOG',
26 | 'junos-icmp-ping': 'PING',
27 | 'junos-icmp-all': 'ALL_ICMP',
28 | 'junos-dns-udp': 'DNS',
29 | 'junos-dns-tcp': 'DNS',
30 | 'junos-ms-sql': 'MS-SQL',
31 | 'junos-sql-monitor': 'MS-SQL',
32 | 'junos-vnc': 'VNC',
33 | 'junos-smb-session': 'SMB',
34 | 'junos-smb': 'SAMBA',
35 | 'junos-radius': 'RADIUS',
36 | 'junos-pptp': 'PPTP',
37 | 'junos-ldap': 'LDAP',
38 | 'junos-internet-locator-service': 'LDAP',
39 | 'junos-ms-rpc-any': 'DCE-RPC',
40 | 'junos-h323': 'H323',
41 | 'junos-ospf': 'OSPF',
42 | 'junos-tcp-any': 'ALL_TCP',
43 | 'junos-udp-any': 'ALL_UDP',
44 | }
45 | palo_translation = {
46 | 'permit': 'allow',
47 | 'junos-http': 'service-http',
48 | 'junos-https': 'service-https',
49 | }
50 |
51 | chpoint_translation = {
52 | 'permit': 'accept',
53 | 'deny': 'drop',
54 | 'disabled': 'false',
55 | 'enabled': 'true',
56 | 'junos-ftp': 'ftp',
57 | 'junos-tftp': 'tftp',
58 | 'junos-rtsp': 'rtsp',
59 | 'junos-ssh': 'ssh',
60 | 'junos-telnet': 'telnet',
61 | 'junos-ping': 'echo-request',
62 | 'junos-ntp': 'ntp-udp',
63 | 'junos-nntp': 'nntp',
64 | 'junos-http': 'http',
65 | 'junos-https': 'https',
66 | 'junos-smtp': 'smtp',
67 | 'junos-syslog': 'syslog',
68 | 'junos-icmp-ping': 'echo-request',
69 | 'junos-dns-udp': 'domain-udp',
70 | 'junos-dns-tcp': 'domain-tcp',
71 | 'junos-ms-sql': 'MS-SQL-Server',
72 | 'junos-sql-monitor': 'MS-SQL-Monitor_UDP',
73 | 'junos-smb-session': 'smb',
74 | 'junos-smb': 'nbsession',
75 | 'junos-radius': 'NEW-RADIUS',
76 | 'junos-radacct': 'NEW-RADIUS-ACCOUNTING',
77 | 'junos-tacacs': 'TACACSplus',
78 | 'junos-pptp': 'pptp-tcp',
79 | 'junos-ldap': 'ldap',
80 | 'junos-internet-locator-service': 'ldap',
81 | 'junos-ms-rpc-any': 'ALL_DCE_RPC',
82 | 'junos-who': 'who',
83 | 'junos-cifs': 'CIFS',
84 | 'junos-ospf': 'ospf',
85 | 'junos-tcp-any': 'unknown_protocol_tcp',
86 | 'junos-udp-any': 'unknown_protocol_udp',
87 | }
88 |
89 | asa_translation = {
90 | 'disabled': 'inactive',
91 | 'junos-ftp': ['tcp', 'ftp'],
92 | 'junos-tftp': ['udp', 'tftp'],
93 | 'junos-rtsp': ['tcp', 'rtsp'],
94 | 'junos-ssh': ['tcp', 'ssh'],
95 | 'junos-telnet': ['tcp', 'telnet'],
96 | 'junos-ping': ['icmp', 'na'],
97 | 'junos-ntp': ['udp', 'ntp'],
98 | 'junos-nntp': ['tcp','nntp'],
99 | 'junos-http': ['tcp', 'http'],
100 | 'junos-https': ['tcp', 'https'],
101 | 'junos-smtp': ['tcp', 'smtp'],
102 | 'junos-syslog': ['udp', 'syslog'],
103 | 'junos-icmp-ping': ['icmp', 'echo'],
104 | 'junos-dns-udp': ['udp', 'domain'],
105 | 'junos-dns-tcp': ['tcp', 'domain'],
106 | 'junos-smb': ['tcp', 'netbios-ssn'],
107 | 'junos-radius': ['udp', 'radius'],
108 | 'junos-radacct': ['udp', 'radius-acct'],
109 | 'junos-tacacs': ['tcp', 'tacacs'],
110 | 'junos-pptp': ['tcp', 'pptp'],
111 | 'junos-ldap': ['tcp', 'ldap'],
112 | 'junos-internet-locator-service': ['tcp', 'ldap'],
113 | 'junos-who': ['udp', 'who'],
114 | 'junos-cifs': ['tcp-udp', 'cifs'],
115 | 'junos-ospf': ['ospf', 'na'],
116 | 'junos-tcp-any': ['tcp', 'na'],
117 | 'junos-udp-any': ['udp', 'na'],
118 | }
119 |
120 | def srx_policy(file: str, vendor: str):
121 | """Uses to provide rule order!"""
122 | if not os.path.exists(f'exported/{vendor}'):
123 | os.makedirs(f'exported/{vendor}')
124 | else:
125 | try:
126 | os.remove(os.path.join(f'exported/{vendor}/', 'policies.txt'))
127 | except:
128 | pass
129 |
130 | with open(f'configs/{file}', 'r') as f:
131 | my_text = xmltodict.parse(f.read())
132 |
133 | os.remove(f'configs/{file}')
134 |
135 | json_formatted = json.dumps(my_text)
136 | dict_formatted = json.loads(json_formatted)
137 | try:
138 | security_cfg = dict_formatted['rpc-reply']['multi-routing-engine-results']['multi-routing-engine-item']['security-policies']['security-context']
139 | except:
140 | security_cfg = dict_formatted['rpc-reply']['security-policies']['security-context']
141 |
142 | position = 1
143 | for main_index in range(len(security_cfg)):
144 | source_zone = security_cfg[main_index]['context-information'].get('source-zone-name', 'None')
145 | destination_zone = security_cfg[main_index]['context-information'].get('destination-zone-name', 'None')
146 | policy = security_cfg[main_index]['policies']
147 |
148 |
149 | for sub_index in range(len(policy)):
150 | policy_src_list = []
151 | policy_dst_list = []
152 | policy_app_list = []
153 |
154 | if isinstance(policy, (list)):
155 | policy_name = policy[sub_index]['policy-information'].get('policy-name', 'None')
156 | policy_state = policy[sub_index]['policy-information'].get('policy-state', 'None')
157 | policy_id = policy[sub_index]['policy-information'].get('policy-identifier', 'None')
158 | policy_seq = policy[sub_index]['policy-information'].get('policy-sequence-number', 'None')
159 | policy_source_address = policy[sub_index]['policy-information']['source-addresses']['source-address']
160 | policy_destination_address = policy[sub_index]['policy-information']['destination-addresses']['destination-address']
161 | policy_application = policy[sub_index]['policy-information']['applications']['application']
162 | if isinstance(policy_source_address, (list)):
163 | for inc_index in range(len(policy_source_address)):
164 | policy_src_address = policy_source_address[inc_index].get('address-name', 'None')
165 | policy_src_list.append(policy_src_address)
166 | else:
167 | policy_src_address = policy_source_address.get('address-name', 'None')
168 | if isinstance(policy_destination_address, (list)):
169 | for inc_index in range(len(policy_destination_address)):
170 | policy_dst_address = policy_destination_address[inc_index].get('address-name', 'None')
171 | policy_dst_list.append(policy_dst_address)
172 | else:
173 | policy_dst_address = policy_destination_address.get('address-name', 'None')
174 | if isinstance(policy_application, (list)):
175 | for inc_index in range(len(policy_application)):
176 | policy_app = policy_application[inc_index].get('application-name', 'None')
177 | if vendor == 'forti' and 'junos' in policy_app:
178 | policy_app = forti_translation.get(policy_app, policy_app)
179 | elif vendor == 'palo' and 'junos' in policy_app:
180 | policy_app = palo_translation.get(policy_app, policy_app)
181 | elif vendor == 'chpoint' and 'junos' in policy_app:
182 | policy_app = chpoint_translation.get(policy_app, policy_app)
183 | elif vendor == 'asa' and 'junos' in policy_app:
184 | policy_app = asa_translation.get(policy_app, policy_app)
185 |
186 | policy_app_list.append(policy_app)
187 | else:
188 | policy_app = policy_application.get('application-name', 'None')
189 | if vendor == 'forti' and 'junos' in policy_app:
190 | policy_app = forti_translation.get(policy_app, policy_app)
191 | elif vendor == 'palo' and 'junos' in policy_app:
192 | policy_app == palo_translation.get(policy_app, policy_app)
193 | elif vendor == 'chpoint' and 'junos' in policy_app:
194 | policy_app = chpoint_translation.get(policy_app, policy_app)
195 | elif vendor == 'asa' and 'junos' in policy_app:
196 | policy_app = asa_translation.get(policy_app, policy_app)
197 |
198 | policy_action = policy[sub_index]['policy-information']['policy-action'].get('action-type', 'None')
199 |
200 | if 'log' in list(policy[sub_index]['policy-information']['policy-action'].keys()):
201 | policy_log = True
202 | else:
203 | policy_log = False
204 | else:
205 | policy_name = policy['policy-information'].get('policy-name', 'None')
206 | policy_state = policy['policy-information'].get('policy-state', 'None')
207 | policy_id = policy['policy-information'].get('policy-identifier', 'None')
208 | # policy_seq = policy['policy-information'].get('policy-sequence-number', 'None')
209 | policy_source_address = policy['policy-information']['source-addresses']['source-address']
210 | policy_destination_address = policy['policy-information']['destination-addresses']['destination-address']
211 | policy_application = policy['policy-information']['applications']['application']
212 |
213 | if isinstance(policy_source_address, (list)):
214 | for inc_index in range(len(policy_source_address)):
215 | policy_src_address = policy_source_address[inc_index].get('address-name', 'None')
216 | policy_src_list.append(policy_src_address)
217 | else:
218 | policy_src_address = policy_source_address.get('address-name', 'None')
219 | if isinstance(policy_destination_address, (list)):
220 | for inc_index in range(len(policy_destination_address)):
221 | policy_dst_address = policy_destination_address[inc_index].get('address-name', 'None')
222 | policy_dst_list.append(policy_dst_address)
223 | else:
224 | policy_dst_address = policy_destination_address.get('address-name', 'None')
225 | if isinstance(policy_application, (list)):
226 | for inc_index in range(len(policy_application)):
227 | policy_app = policy_application[inc_index].get('application-name', 'None')
228 | if vendor == 'forti' and 'junos' in policy_app:
229 | policy_app = forti_translation.get(policy_app, policy_app)
230 | elif vendor == 'palo' and 'junos' in policy_app:
231 | policy_app = palo_translation.get(policy_app, policy_app)
232 | elif vendor == 'chpoint' and 'junos' in policy_app:
233 | policy_app = chpoint_translation.get(policy_app, policy_app)
234 | elif vendor == 'asa' and 'junos' in policy_app:
235 | policy_app = asa_translation.get(policy_app, policy_app)
236 |
237 | if vendor == 'chpoint':
238 | if policy_app[:1].isdigit():
239 | policy_app = 'custom_' + policy_app
240 | policy_app_list.append(policy_app)
241 | else:
242 | policy_app = policy_application.get('application-name', 'None')
243 | if vendor == 'forti' and 'junos' in policy_app:
244 | policy_app = forti_translation.get(policy_app, policy_app)
245 | elif vendor == 'palo' and 'junos' in policy_app:
246 | policy_app = palo_translation.get(policy_app, policy_app)
247 | elif vendor == 'chpoint' and 'junos' in policy_app:
248 | policy_app = chpoint_translation.get(policy_app, policy_app)
249 | elif vendor == 'asa' and 'junos' in policy_app:
250 | policy_app = asa_translation.get(policy_app, policy_app)
251 |
252 | if vendor == 'chpoint':
253 | if policy_app[:1].isdigit():
254 | policy_app = 'custom_' + policy_app
255 |
256 |
257 | policy_action = policy['policy-information']['policy-action'].get('action-type', 'None')
258 |
259 | if 'log' in list(policy['policy-information']['policy-action'].keys()):
260 | policy_log = True
261 | else:
262 | policy_log = False
263 | if policy_src_list:
264 | policy_src_address = ' '.join(policy_src_list)
265 | if policy_dst_list:
266 | policy_dst_address = ' '.join(policy_dst_list)
267 | if policy_app_list:
268 | try:
269 | policy_app = ' '.join(policy_app_list)
270 | except:
271 | policy_app = policy_app_list
272 |
273 | if vendor == 'forti':
274 | policy_state = forti_translation.get(policy_state, policy_state)
275 | policy_action = forti_translation.get(policy_action, policy_action)
276 | if 'any' in policy_src_address:
277 | policy_src_address = 'all'
278 | if 'any' in policy_dst_address:
279 | policy_dst_address = 'all'
280 | if policy_app == 'any':
281 | policy_app = 'ALL'
282 | if len(policy_name) > 34:
283 | policy_name = policy_name[:34]
284 |
285 | forti = Forti_DST()
286 | forti.policy(
287 | policy_name,
288 | source_zone,
289 | destination_zone,
290 | policy_src_address,
291 | policy_dst_address,
292 | policy_app,
293 | policy_log,
294 | policy_state,
295 | policy_action,
296 | policy_id
297 | )
298 |
299 | elif vendor == 'asa':
300 | policy_action = asa_translation.get(policy_action, policy_action)
301 | asa = ASA_DST()
302 | asa.policy(
303 | policy_name,
304 | source_zone,
305 | destination_zone,
306 | policy_src_address,
307 | policy_dst_address,
308 | policy_app,
309 | policy_log,
310 | policy_state,
311 | policy_action,
312 | policy_id
313 | )
314 | elif vendor == 'palo':
315 | policy_action = palo_translation.get(policy_action, policy_action)
316 | palo = Palo_DST()
317 | palo.policy(
318 | policy_name,
319 | source_zone,
320 | destination_zone,
321 | policy_src_address,
322 | policy_dst_address,
323 | policy_app,
324 | policy_log,
325 | policy_state,
326 | policy_action
327 | )
328 |
329 | elif vendor == 'chpoint':
330 | policy_action = chpoint_translation.get(policy_action, policy_action)
331 | policy_state = chpoint_translation.get(policy_state, policy_state)
332 |
333 | if policy_dst_list:
334 | dst_list = []
335 | for i in range(len(policy_dst_list)):
336 | dst_list.append(f'destination.{i+1} "{policy_dst_list[i]}"')
337 | policy_dst_address = ' '.join(dst_list)
338 | else:
339 | policy_dst_address = f'destination "{policy_dst_address}"'
340 |
341 | if policy_src_list:
342 | src_list = []
343 | for i in range(len(policy_src_list)):
344 | src_list.append(f'source.{i+1} "{policy_src_list[i]}"')
345 | policy_src_address = ' '.join(src_list)
346 | else:
347 | policy_src_address = f'source "{policy_src_address}"'
348 | if policy_app_list:
349 | app_list = []
350 | for i in range(len(policy_app_list)):
351 | if policy_app_list[i][:1].isdigit():
352 | policy_app = 'custom_' + policy_app_list[i]
353 | else:
354 | policy_app = policy_app_list[i]
355 | app_list.append(f'service.{i+1} "{policy_app}"')
356 | policy_app = ' '.join(app_list)
357 | else:
358 | if policy_app[:1].isdigit():
359 | policy_app = 'custom_' + policy_app
360 |
361 | policy_app = f'service "{policy_app}"'
362 |
363 | chpoint = CHPoint_DST()
364 | chpoint.policy(
365 | policy_name,
366 | source_zone,
367 | destination_zone,
368 | policy_src_address,
369 | policy_dst_address,
370 | policy_app,
371 | policy_log,
372 | policy_state,
373 | policy_action,
374 | policy_id,
375 | position
376 | )
377 |
378 |
379 | position += 1
380 |
--------------------------------------------------------------------------------
/resources/web/static/files.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | body{
8 | background-color: #bbb;
9 | color: orange;
10 | font-weight: bolder;
11 | }
12 |
13 | #container {
14 | margin: 30px auto;
15 | max-width: 450px;
16 | padding: 20px;
17 | background-color: white;
18 | border: solid black 2px;
19 | border-radius: 5px;
20 | }
21 |
22 | p {
23 | margin-bottom: 20px;
24 | font-size: larger;
25 | font-weight: bolder;
26 | color: #111;
27 | text-align: center;
28 | }
29 |
30 | a{
31 | text-decoration: none;
32 | font-size: large;
33 | color: #111;
34 | text-decoration: underline;
35 | }
36 |
37 | nav {
38 | max-width: 100%;
39 | background-color: #444;
40 | height: 50px;
41 | display: flex;
42 | justify-content: space-between;
43 | }
44 |
45 | nav p {
46 | margin: 15px;
47 | color: orange;
48 | font-weight: bold;
49 | text-decoration: none;
50 | display: flex;
51 | align-items: center;
52 | }
53 |
54 | nav a {
55 | margin: 15px;
56 | color: orange;
57 | font-weight: bold;
58 | text-decoration: none;
59 | display: flex;
60 | align-items: center;
61 | }
62 |
63 | nav .linked {
64 | display: flex;
65 |
66 | }
--------------------------------------------------------------------------------
/resources/web/static/script.js:
--------------------------------------------------------------------------------
1 | function ChangeDropdowns(value){
2 | if(value=="netconf" || value=="rest"){
3 | document.getElementById('file').style.display='none';
4 | for (i = 0; i < 4; i++){
5 | document.getElementsByClassName('remote')[i].style.display='block';
6 | }
7 | document.getElementById('host').setAttribute('required', true);
8 | document.getElementById('username').setAttribute('required', true);
9 | document.getElementById('password').setAttribute('required', true);
10 | document.getElementById('port').setAttribute('required', true);
11 | if(value=="rest"){
12 | document.getElementById('protocol').setAttribute('required', true);
13 | document.getElementsByClassName('protocol')[0].style.display='block';
14 | }
15 | if(value=="netconf"){
16 | document.getElementById('protocol').removeAttribute('required');
17 | document.getElementsByClassName('protocol')[0].style.display='none';
18 | }
19 | }else if(value=="file"){
20 | document.getElementById('file').style.display='block';
21 | for (i = 0; i < 4; i++) {
22 | document.getElementsByClassName('remote')[i].style.display='none';
23 | }
24 | document.getElementsByClassName('protocol')[0].style.display='none';
25 | document.getElementById('host').removeAttribute('required');
26 | document.getElementById('username').removeAttribute('required');
27 | document.getElementById('password').removeAttribute('required');
28 | document.getElementById('protocol').removeAttribute('required');
29 | document.getElementById('port').removeAttribute('required');
30 | document.getElementById('protocol').removeAttribute('required');
31 | }
32 | }
33 |
34 | function configOptions(value) {
35 | if(value=='config'){
36 | document.getElementById('config-box').style.display='block';
37 | }
38 | else if(value=='policy'){
39 | document.getElementById('config-box').style.display='none';
40 | }
41 | }
42 |
43 |
44 | function updateSelect(changedSelect, selectId) {
45 | var otherSelect = document.getElementById(selectId);
46 | for (var i = 0; i < otherSelect.options.length; ++i) {
47 | otherSelect.options[i].disabled = false;
48 | }
49 | if (changedSelect.selectedIndex == 0) {
50 | return;
51 | }
52 | otherSelect.options[changedSelect.selectedIndex].disabled = true;
53 | }
54 |
55 |
56 |
--------------------------------------------------------------------------------
/resources/web/static/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | body{
8 | background-color: #bbb;
9 | }
10 |
11 | #container {
12 | margin: 30px auto;
13 | max-width: 450px;
14 | padding: 20px;
15 | }
16 |
17 | .form-wrap {
18 | background-color: white;
19 | padding: 15px 25px;
20 | color: #333;
21 | border: solid 2px black;
22 | border-radius: 5px;
23 | }
24 |
25 | p {
26 | text-align: center;
27 | font-size: larger;
28 | font-weight: bolder;
29 | }
30 |
31 | .form-wrap .form-group {
32 | margin-top: 15px;
33 | }
34 |
35 |
36 | .form-wrap .form-group label{
37 | display: block;
38 | color: #111;
39 | margin-bottom: 5px;
40 | font-weight: bold;
41 | }
42 | .form-wrap .remote, .form-wrap .protocol {
43 | display: none;
44 | }
45 |
46 | .form-wrap .config-box{
47 | display: none;
48 | }
49 |
50 | .form-wrap .form-group input, select{
51 | width: 100%;
52 | padding: 10px;
53 | border: #ddd 1px solid;
54 | border-radius: 5px;
55 | }
56 |
57 | .form-wrap button{
58 | display: block;
59 | width: 100%;
60 | padding: 10px;
61 | margin-top: 10px;
62 | background-color: orange;
63 | color: black;
64 | font-weight: bold;
65 | }
66 |
67 | nav {
68 | max-width: 100%;
69 | background-color: #444;
70 | height: 50px;
71 | display: flex;
72 | justify-content: space-between;
73 | }
74 |
75 | nav p {
76 | margin: 15px;
77 | color: orange;
78 | font-weight: bold;
79 | text-decoration: none;
80 | display: flex;
81 | align-items: center;
82 | }
83 |
84 | nav a {
85 | margin: 15px;
86 | color: orange;
87 | font-weight: bold;
88 | text-decoration: none;
89 | display: flex;
90 | align-items: center;
91 | font-size: large;
92 | }
93 |
94 | nav .linked {
95 | display: flex;
96 |
97 | }
98 |
99 | .form-wrap .config-box label, .form-wrap .config-box input{
100 | width:auto;
101 | display: unset;
102 | }
103 |
--------------------------------------------------------------------------------
/resources/web/templates/exported_vendor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Download Output
8 |
9 |
10 |
19 |
20 |
Output files
21 | {% for file in dloads %}
22 | {% if 'keep' not in file %}
23 | ->
{{ file }}
24 | {% endif %}
25 | {% endfor %}
26 |
27 |
28 |
--------------------------------------------------------------------------------
/resources/web/templates/files.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Download Output
8 |
9 |
10 |
19 |
20 |
Output files
21 | {% for file in dloads %}
22 | {% if 'keep' not in file %}
23 | ->
{{ file }}
24 | {% endif %}
25 | {% endfor %}
26 |
27 |
28 |
--------------------------------------------------------------------------------
/resources/web/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | FW Migration Tool
9 |
10 |
11 |
20 |
120 |
128 |
129 |
--------------------------------------------------------------------------------