diff --git a/.gitignore b/.gitignore index ac50e35b2..a5024f784 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +__pycache__ +config.json +.env .vscode config.json config/ diff --git a/README.md b/README.md index 28a4d5349..1fcbbc698 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,60 @@ -CloudMapper -======== +CloudMapper Flake Fork +====================== -**Note** the Network Visualization functionality (command `prepare`) is no longer maintained. +## About this flake fork -CloudMapper helps you analyze your Amazon Web Services (AWS) environments. -The original purpose was to generate network diagrams and display them in your browser (functionality no longer maintained). -It now contains much more functionality, including auditing for security issues. +The upstream Cloudmapper project has been abandoned. The used python libraries +are obsolete and therefor it's difficult, even using docker, to get cloudmapper +working. This is sad, because cloudmapper still is very useful. + +This fork adds a flake.nix file to preserve a working cloudmapper for +the future. If you wanna try it make sure you have [nix](https://nixos.org) +installed with flakes enabled. + +## Usage + +First read upstream [Setup](#setup) documentation. + +### nix develop + +Open the development shell. + +```bash +nix development github:wearetechnative/cloudmapper-flake +``` + +You can now run `python cloudmapper [command]` e.g. `python cloudmapper collect` + +### ~~nix run~~ + +~~Alternatively you can run cloudmapper instantly using the `nix run` method.~~ + +## Supported commands + +Not all commands are working because not all python modules are backported. +These commands has been tested to function correctly. + +- collect +- configure +- find_admins +- find_unused +- iam_report +- prepare +- public + stats +- report +- weboftrust +- webserver + +# CloudMapper (upstream readme) + +**Note** the Network Visualization functionality (command `prepare`) is no +longer maintained. + +CloudMapper helps you analyze your Amazon Web Services (AWS) environments. The +original purpose was to generate network diagrams and display them in your +browser (functionality no longer maintained). It now contains much more +functionality, including auditing for security issues. - [Network mapping demo](https://duo-labs.github.io/cloudmapper/) - [Report demo](https://duo-labs.github.io/cloudmapper/account-data/report.html) diff --git a/__init__.py b/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..49829a05f --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1741822597, + "narHash": "sha256-ToQZtW0u7s12b4DYA2/mvc/u7xAdM9J+6A73n6rb7IA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2f8a52a3d2d601d49a25127e574597b335144c57", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..e7e7ec8cb --- /dev/null +++ b/flake.nix @@ -0,0 +1,43 @@ +{ + description = "Cloudmapper"; + + inputs = { nixpkgs.url = "github:NixOS/nixpkgs"; }; + + outputs = { self, nixpkgs }: + let + allSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + + overlay = import ./overlay.nix; + + forAllSystems = f: + nixpkgs.lib.genAttrs allSystems (system: + f { + pkgs = import nixpkgs { + inherit system; + overlays = [ overlay ]; + }; + }); + in { + + packages = forAllSystems ({ pkgs }: + let + python = pkgs.python311; + packages = import ./python-packages.nix { inherit python; }; + in + { + default = pkgs.callPackage ./package.nix { inherit python; inherit packages; }; + cloudmapper = pkgs.callPackage ./package.nix { inherit python; inherit packages; }; + }); + + devShells = forAllSystems ({ pkgs }: + let + python = pkgs.python311; + packages = import ./python-packages.nix { inherit python; }; + in + { + default = pkgs.mkShell { + inherit packages; + }; + }); + }; +} diff --git a/overlay.nix b/overlay.nix new file mode 100644 index 000000000..f9a0c2365 --- /dev/null +++ b/overlay.nix @@ -0,0 +1,92 @@ +(self0: super0: + let + myOverride = { + packageOverrides = self: super: { + + "parliament" = super.buildPythonPackage rec { + pname = "parliament"; + version = "1.5.2"; + src = super0.fetchurl { + url = + "https://files.pythonhosted.org/packages/ab/a8/47e63d872a4cbe4d48fb6d2df08ebf87c7feb1b8349030b180a0782299eb/parliament-1.5.2-py3-none-any.whl"; + sha256 = + "1d8j51429df7j1abqsgakwidcq4w4yn0aisfs6vdsnxqz5744l0r"; + }; + format = "wheel"; + doCheck = false; + buildInputs = [ ]; + checkInputs = [ ]; + nativeBuildInputs = [ ]; + propagatedBuildInputs = [ + super.pyyaml + super.boto3 + super.jmespath + self."json-cfg" + self.setuptools + ]; + }; + + "json-cfg" = super.buildPythonPackage rec { + pname = "json-cfg"; + version = "0.4.2"; + src = super0.fetchurl { + url = + "https://files.pythonhosted.org/packages/b7/f5/ecdfc00830bcbaf7743f0237cf4f3ced5511d57257408db01aa320e09458/json_cfg-0.4.2-py2.py3-none-any.whl"; + sha256 = + "1j0nnx48srkhvs7ibb6r1jwzvgvj268cqq07cpxbscvigaix1j3h"; + }; + format = "wheel"; + doCheck = false; + buildInputs = [ ]; + checkInputs = [ ]; + nativeBuildInputs = [ ]; + propagatedBuildInputs = [ self."kwonly-args" ]; + }; + + "kwonly-args" = super.buildPythonPackage rec { + pname = "kwonly-args"; + version = "1.0.10"; + src = super0.fetchurl { + url = + "https://files.pythonhosted.org/packages/00/37/3251dc1c11f5e9c4b8fb1b3f433da4b55ec52e3fe5c14b13a2a558990260/kwonly_args-1.0.10-py2.py3-none-any.whl"; + sha256 = + "1jz1f977lfd639my2xqjd9yndgkg0hxhb8rdlwzw0g8i077nrkiy"; + }; + format = "wheel"; + doCheck = false; + buildInputs = [ ]; + checkInputs = [ ]; + nativeBuildInputs = [ ]; + propagatedBuildInputs = [ ]; + }; + + pyjq = super.buildPythonPackage rec { + pname = "pyjq"; + version = "2.6.0"; + src = super.fetchPypi { + inherit pname version; + sha256 = + "e083f326f4af8b07b8ca6424d1f99afbdd7db9b727284da5f919b9816077f2e4"; + }; + format = "setuptools"; + doCheck = false; + buildInputs = [ ]; + checkInputs = [ ]; + nativeBuildInputs = [ + super0.libtool + super0.automake + super0.autoconf + super0.pkg-config + ]; + propagatedBuildInputs = [ ]; + }; + + }; + }; + in { + # Add an override for each required python version. + # There’s currently no way to add a package that’s automatically picked up by + # all python versions, besides editing python-packages.nix + python3 = super0.python3.override myOverride; + python311 = super0.python311.override myOverride; + }) diff --git a/package.nix b/package.nix new file mode 100644 index 000000000..9c6cfbb21 --- /dev/null +++ b/package.nix @@ -0,0 +1,14 @@ +{ pkgs, python, packages, ... }: + +pkgs.python3Packages.buildPythonPackage rec { + pname = "cloudmapper"; + version = "2.10.0"; + src = ./.; + + propagatedBuildInputs = packages; + + postInstall = '' + cp $out/bin/cloudmapper.py $out/bin/cloudmapper + ''; + +} diff --git a/python-packages.nix b/python-packages.nix new file mode 100644 index 000000000..3fe12fd23 --- /dev/null +++ b/python-packages.nix @@ -0,0 +1,22 @@ +{ python, ... }: +[ + (python.withPackages (ps: + with ps; [ + boto3 + botocore + netaddr + pyjq + python-dateutil + pyyaml + jinja2 + parliament + matplotlib + pandas + seaborn + policyuniverse + requests + s3transfer + toml + urllib3 + ])) +] diff --git a/requirements.txt b/requirements.txt index 3e5bce870..65820ad69 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -astroid==2.8.4 +astroid==3.8.4 autoflake==1.4 autopep8==1.6.0 boto3==1.19.10 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..d3963134e --- /dev/null +++ b/setup.py @@ -0,0 +1,32 @@ +#from setuptools import setup, find_packages +from setuptools import setup, find_packages + +setup( + name="cloudmapper", + version="2.10.0", + packages=find_packages(), + install_requires=[ + 'boto3', + 'botocore', + 'netaddr', + 'pyjq', + 'python-dateutil', + 'pyyaml', + 'jinja2', + 'parliament', + 'matplotlib', + 'pandas', + 'seaborn', + 'policyuniverse', + 'requests', + 's3transfer', + 'toml', + 'urllib3', + ], + scripts=['cloudmapper.py'], +# entry_points={ +# 'console_scripts': [ +# 'cloudmapper = cloudmapper:main', +# ], +# }, +) diff --git a/stats_config.yaml b/stats_config.yaml index e0880bc4f..8d71532de 100644 --- a/stats_config.yaml +++ b/stats_config.yaml @@ -128,15 +128,15 @@ query: .logGroups|length source: logs-describe-log-groups verbose: true -- name: ACM Certificates +- name: ACM Certificates query: .CertificateSummaryList|length - source: acm-list-certificates + source: acm-list-certificates verbose: true -- name: DynamoDB Tables +- name: DynamoDB Tables query: .TableNames|length - source: dynamodb-list-tables + source: dynamodb-list-tables verbose: true - name: Internet Gateways query: '[.InternetGateways[]?.Attachments[]?|select(.State == "available")]|length' - source: describe-internet-gateways + source: describe-internet-gateways verbose: true