diff options
Diffstat (limited to 'web-tools/bin')
-rwxr-xr-x | web-tools/bin/bin/update | 24 | ||||
-rw-r--r-- | web-tools/bin/index-test.html | 298 | ||||
-rw-r--r-- | web-tools/bin/index.html | 298 | ||||
-rwxr-xr-x | web-tools/bin/tools-test.py | 260 | ||||
-rwxr-xr-x | web-tools/bin/tools.py | 260 |
5 files changed, 1140 insertions, 0 deletions
diff --git a/web-tools/bin/bin/update b/web-tools/bin/bin/update new file mode 100755 index 0000000..4de2fd2 --- /dev/null +++ b/web-tools/bin/bin/update @@ -0,0 +1,24 @@ +#!/bin/sh + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +ssh tools.bfh.info \ + "cd /srv/tools.bfh.info/bin && \ + git clean -dxf > /dev/null 2>&1 && + git checkout -f HEAD && + git pull --rebase" diff --git a/web-tools/bin/index-test.html b/web-tools/bin/index-test.html new file mode 100644 index 0000000..09861e4 --- /dev/null +++ b/web-tools/bin/index-test.html @@ -0,0 +1,298 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="author" content="bfh.info"> + <meta name="description" content="tools.bfh.info"> + <meta name="generator" content="bfh-linux-sysadmin@lists.bfh.science"> + + <title>tools.bfh.info</title> + <link rel="canonical" href="https://bfh.info"> + + <!-- Bootstrap core CSS --> + <link href="/_static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this template --> + <link href="/_static/dejavu-fonts/dejavu-fonts.css" rel="stylesheet"> + <link href="/_static/fontawesome-pro/css/all.min.css" rel="stylesheet"> + + <link href="/_static/local/body.css" rel="stylesheet"> + <link href="/_static/local/font.css" rel="stylesheet"> + <link href="/_static/local/footer.css" rel="stylesheet"> + </head> + + <body> + <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> + <a class="navbar-brand" href="/"><b>tools.bfh.info</b></a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsDefault" aria-controls="navbarsDefault" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarsDefault"> + <ul class="navbar-nav mr-auto"> + </ul> + </div> + </nav> + + <main role="main" class="container"> + + <div class="content"> + +<!-- +Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> + +SPDX-License-Identifier: GPL-3.0+ + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +--> + +<a name="top"></a> +<h1><i class="fa-fw far fa-tools"></i> Network Tools<sup><small>TEST</small></sup> <small>(<a href="/api">API</a>)</small></h1> +<div style="height: 2em"></div> + +<script src="/_static/jquery/jquery.min.js"></script> + +<script> + $(document).ready(function(){ + $("[type=button]").click(function() { + var command = $(this).data("command"); + var protocol = $("input[name='protocol']:checked").val(); + var target = document.getElementById("target").value; + var cgi = command + "&protocol=" + protocol + "&target=" + target; + $.ajax({url: cgi, success: function(result){ + $("#output").text(result); + document.getElementById('output-hidden').style.display = 'block'; + $(document).scrollTop( $("#output").offset().top -125); + }}); + }); + + $("[type=reset]").click(function() { + $("#dual-stack").click(); + $('.btn-group').find('reset').removeClass('active') + .end().find('[type="reset"]').prop('checked', false); + document.getElementById('output-hidden').style.display = 'none'; + $("#target").focus(); + $("#target").prop('autofocus'); + }); + }); +</script> + +<style type="text/css"> + label, [type="button"], [type="reset"], [type="text"] { + margin-top: 0.5em; + } +</style> + +<form id="form"> + <div class="form-group"> + <div class="row"> + <div class="col-md-6"> + <b>Target</b> + <input id="target" placeholder="IP address/subnet, FQDN, ASN, Internet resources..." style="width: 100%;" type="text" autofocus /> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <b>Settings</b><br /> + <input class="btn btn-light btn-sm" type="reset" value="Reset" /> + + <div class="btn-group btn-group-toggle" data-toggle="buttons"> + <label class="btn btn-light btn-sm active"> + <input type="radio" name="protocol" id="dual-stack" value="dual-stack" checked> Dual-stack + </label> + <label class="btn btn-light btn-sm"> + <input type="radio" name="protocol" id="ipv4-only" value="ipv4-only"> IPv4-only + </label> + <label class="btn btn-light btn-sm"> + <input type="radio" name="protocol" id="ipv6-only" value="ipv6-only"> IPv6-only + </label> + </div> + + <div style="height: 1em"></div> + </div> + </div> + </div> +</form> + +<hr /> + +<div class="row"> + <div class="col-md-6"> + <b>Network</b><br /> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=ping">ping</button> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=traceroute">traceroute</button> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=tcptraceroute">tcptraceroute</button> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=whois">whois</button> + + <div style="height: 1em"></div> + + <b>Security</b><br /> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=nmap">nmap</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=testssl">testssl</button> + + <div style="height: 1em"></div> + + <b>other</b><br /> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=my-ip&target=none">My IP</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=my-browser&target=none">My browser</button> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <b>DNS</b><br /> + <small><b>Address-related records</b></small><br /> + <button type="button" class="btn btn-primary" data-command="/bin/tools-test.py?command=kdig&query=ANY">ANY</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools-test.py?command=kdig&query=A">A</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools-test.py?command=kdig&query=AAAA">AAAA</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools-test.py?command=kdig&query=CNAME">CNAME</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools-test.py?command=kdig&query=DNAME">DNAME</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools-test.py?command=kdig&query=PTR">PTR</button> + + <div style="height: 1em"></div> + + <small><b>Informational records</b></small><br /> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=APL">APL</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=HINFO">HINFO</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=LOC">LOC</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=RP">RP</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=SOA">SOA</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=SRV">SRV</button> + <button type="button" class="btn btn-info" data-command="/bin/tools-test.py?command=kdig&query=TXT">TXT</button> + + <div style="height: 1em"></div> + + <small><b>DNSSEC records</b></small><br /> + <button type="button" class="btn btn-secondary" data-command="/bin/tools-test.py?command=kdig&query=CDNSKEY">CDNSKEY</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools-test.py?command=kdig&query=CDS">CDS</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools-test.py?command=kdig&query=DNSKEY">DNSKEY</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools-test.py?command=kdig&query=DS">DS</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools-test.py?command=kdig&query=RRSIG">RRSIG</button> + + <div style="height: 1em"></div> + + <small><b>Security-related records</b></small><br /> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=kdig&query=CAA">CAA</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=kdig&query=NSEC3">NSEC3</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=kdig&query=NSEC3PARAM">NSEC3PARAM</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=kdig&query=SSHFP">SSHFP</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools-test.py?command=kdig&query=TLSA">TLSA</button> + + <div style="height: 1em"></div> + + <small><b>other records and types</b></small><br /> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=kdig&query=AXFR">AXFR*</button> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=kdig&query=MX">MX</button> + <button type="button" class="btn btn-success" data-command="/bin/tools-test.py?command=kdig&query=NS">NS</button> + + <div style="height: 1em"></div> + + <small><b>Legacy records</b></small><br /> + <button type="button" class="btn btn-danger" data-command="/bin/tools-test.py?command=kdig&query=NSEC">NSEC</button> + <button type="button" class="btn btn-danger" data-command="/bin/tools-test.py?command=kdig&query=SPF">SPF</button> + + <div style="height: 1em"></div> + </div> +</div> + +<div class="row"> + <div class="col-md-6"> + <small><b>Notes:</b> + <ul> + <li>testssl can take up to 5min (with currently no output until the end)</li> + </ul></small> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <small><b>*</b> only available for BFH authoritative zones</small> + + <div style="height: 1em"></div> + </div> +</div> + +<hr /> + +<div id="output-hidden" style="display: none;"> +<a name="output"></a> +<a href="#top"><button type="button" class="btn btn-light btn-sm float-right">↑</button></a><br /> +<b>Output</b><br /> +<pre> +<textarea id="output" readonly rows="25" style="background: #f1f1f1; width: 100%;"></textarea> +</pre> +</div> + +<div style="height: 1em"></div> + + + </div> + + </main><!-- /.container --> + + <footer class="footer py-5"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <a href="https://www.bfh.ch"><img src="/logo.svg" style="height: 112.5px" /></a><br /> + <br /> + </div> + <div class="col-md-3"> + <small> + <strong><i class="fa-fw fas fa-map-marker"></i> Address</strong><br /> + <a class="text-muted" href="https://www.openstreetmap.org/search?query=Dammweg 3%2C 3013 Bern">Berner Fachhochschule<br /> + IT-Services<br /> + Team Linux & Infrastructure Services<br /> + Dammweg 3, CH-3013 Bern</a><br /> + <br /> + </small> + </div> + <div class="col-md-3"> + <small> + <strong><i class="fa-fw fas fa-phone"></i> Phone</strong><br /> + <a class="text-muted" href="#">+41 31 848 48 48</a><br /> + <br /> + <strong><i class="fa-fw fas fa-envelope"></i> Email</strong><br /> + <a class="text-muted" href="mailto:bfh-linux-sysadmin@lists.bfh.science?subject=BFH.science:%20Feedback">bfh-linux-sysadmin@lists.bfh.science</a><br /> + <br /> + </small> + </div> + <div class="col-md-4"> + <small> + <br /> + <br /> + <br /> + <br /> + <i class="fa-fw fas fa-copyright"></i> <a class="text-muted" href="https://bfh.science/other/legal">2021</a> + + <a style="color: inherit;" href="https://bfh.science/other/legal" title="Legal Information"><i class="fa-fw fas fa-balance-scale"></i></a> <a class="text-muted" href="https://bfh.science/other/legal" title="Legal Information">Legal Information</a> + + <a class="a-hover-red" href="https://git.bfh.info" title="Made with Love and Git"><i class="fa-fw fas fa-heart"></i></a> <a class="text-muted" href="https://git.bfh.info" title="Made with Love and Git">Source Code</a><br /> + <br /> + </small> + </div> + </div> + </div> + </footer> + + <!-- Bootstrap core JS --> + <script src="/_static/popperjs/popper.min.js"></script> + <script src="/_static/bootstrap/js/bootstrap.min.js"></script> + + <!-- Custom scripts for this template --> + <script src="/_static/local/table.js"></script> + </body> +</html> diff --git a/web-tools/bin/index.html b/web-tools/bin/index.html new file mode 100644 index 0000000..c54f22f --- /dev/null +++ b/web-tools/bin/index.html @@ -0,0 +1,298 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="author" content="bfh.info"> + <meta name="description" content="tools.bfh.info"> + <meta name="generator" content="bfh-linux-sysadmin@lists.bfh.science"> + + <title>tools.bfh.info</title> + <link rel="canonical" href="https://bfh.info"> + + <!-- Bootstrap core CSS --> + <link href="/_static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this template --> + <link href="/_static/dejavu-fonts/dejavu-fonts.css" rel="stylesheet"> + <link href="/_static/fontawesome-pro/css/all.min.css" rel="stylesheet"> + + <link href="/_static/local/body.css" rel="stylesheet"> + <link href="/_static/local/font.css" rel="stylesheet"> + <link href="/_static/local/footer.css" rel="stylesheet"> + </head> + + <body> + <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> + <a class="navbar-brand" href="/"><b>tools.bfh.info</b></a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsDefault" aria-controls="navbarsDefault" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + + <div class="collapse navbar-collapse" id="navbarsDefault"> + <ul class="navbar-nav mr-auto"> + </ul> + </div> + </nav> + + <main role="main" class="container"> + + <div class="content"> + +<!-- +Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> + +SPDX-License-Identifier: GPL-3.0+ + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +--> + +<a name="top"></a> +<h1><i class="fa-fw far fa-tools"></i> Network Tools<sup><small>beta</small></sup> <small>(<a href="/api">API</a>)</small></h1> +<div style="height: 2em"></div> + +<script src="/_static/jquery/jquery.min.js"></script> + +<script> + $(document).ready(function(){ + $("[type=button]").click(function() { + var command = $(this).data("command"); + var protocol = $("input[name='protocol']:checked").val(); + var target = document.getElementById("target").value; + var cgi = command + "&protocol=" + protocol + "&target=" + target; + $.ajax({url: cgi, success: function(result){ + $("#output").text(result); + document.getElementById('output-hidden').style.display = 'block'; + $(document).scrollTop( $("#output").offset().top -125); + }}); + }); + + $("[type=reset]").click(function() { + $("#dual-stack").click(); + $('.btn-group').find('reset').removeClass('active') + .end().find('[type="reset"]').prop('checked', false); + document.getElementById('output-hidden').style.display = 'none'; + $("#target").focus(); + $("#target").prop('autofocus'); + }); + }); +</script> + +<style type="text/css"> + label, [type="button"], [type="reset"], [type="text"] { + margin-top: 0.5em; + } +</style> + +<form id="form"> + <div class="form-group"> + <div class="row"> + <div class="col-md-6"> + <b>Target</b> + <input id="target" placeholder="IP address/subnet, FQDN, ASN, Internet resources..." style="width: 100%;" type="text" autofocus /> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <b>Settings</b><br /> + <input class="btn btn-light btn-sm" type="reset" value="Reset" /> + + <div class="btn-group btn-group-toggle" data-toggle="buttons"> + <label class="btn btn-light btn-sm active"> + <input type="radio" name="protocol" id="dual-stack" value="dual-stack" checked> Dual-stack + </label> + <label class="btn btn-light btn-sm"> + <input type="radio" name="protocol" id="ipv4-only" value="ipv4-only"> IPv4-only + </label> + <label class="btn btn-light btn-sm"> + <input type="radio" name="protocol" id="ipv6-only" value="ipv6-only"> IPv6-only + </label> + </div> + + <div style="height: 1em"></div> + </div> + </div> + </div> +</form> + +<hr /> + +<div class="row"> + <div class="col-md-6"> + <b>Network</b><br /> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=ping">ping</button> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=traceroute">traceroute</button> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=tcptraceroute">tcptraceroute</button> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=whois">whois</button> + + <div style="height: 1em"></div> + + <b>Security</b><br /> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=nmap">nmap</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=testssl">testssl</button> + + <div style="height: 1em"></div> + + <b>other</b><br /> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=my-ip&target=none">My IP</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=my-browser&target=none">My browser</button> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <b>DNS</b><br /> + <small><b>Address-related records</b></small><br /> + <button type="button" class="btn btn-primary" data-command="/bin/tools.py?command=kdig&query=ANY">ANY</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools.py?command=kdig&query=A">A</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools.py?command=kdig&query=AAAA">AAAA</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools.py?command=kdig&query=CNAME">CNAME</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools.py?command=kdig&query=DNAME">DNAME</button> + <button type="button" class="btn btn-primary" data-command="/bin/tools.py?command=kdig&query=PTR">PTR</button> + + <div style="height: 1em"></div> + + <small><b>Informational records</b></small><br /> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=APL">APL</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=HINFO">HINFO</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=LOC">LOC</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=RP">RP</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=SOA">SOA</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=SRV">SRV</button> + <button type="button" class="btn btn-info" data-command="/bin/tools.py?command=kdig&query=TXT">TXT</button> + + <div style="height: 1em"></div> + + <small><b>DNSSEC records</b></small><br /> + <button type="button" class="btn btn-secondary" data-command="/bin/tools.py?command=kdig&query=CDNSKEY">CDNSKEY</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools.py?command=kdig&query=CDS">CDS</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools.py?command=kdig&query=DNSKEY">DNSKEY</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools.py?command=kdig&query=DS">DS</button> + <button type="button" class="btn btn-secondary" data-command="/bin/tools.py?command=kdig&query=RRSIG">RRSIG</button> + + <div style="height: 1em"></div> + + <small><b>Security-related records</b></small><br /> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=kdig&query=CAA">CAA</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=kdig&query=NSEC3">NSEC3</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=kdig&query=NSEC3PARAM">NSEC3PARAM</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=kdig&query=SSHFP">SSHFP</button> + <button type="button" class="btn btn-warning" data-command="/bin/tools.py?command=kdig&query=TLSA">TLSA</button> + + <div style="height: 1em"></div> + + <small><b>other records and types</b></small><br /> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=kdig&query=AXFR">AXFR*</button> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=kdig&query=MX">MX</button> + <button type="button" class="btn btn-success" data-command="/bin/tools.py?command=kdig&query=NS">NS</button> + + <div style="height: 1em"></div> + + <small><b>Legacy records</b></small><br /> + <button type="button" class="btn btn-danger" data-command="/bin/tools.py?command=kdig&query=NSEC">NSEC</button> + <button type="button" class="btn btn-danger" data-command="/bin/tools.py?command=kdig&query=SPF">SPF</button> + + <div style="height: 1em"></div> + </div> +</div> + +<div class="row"> + <div class="col-md-6"> + <small><b>Notes:</b> + <ul> + <li>testssl can take up to 5min (with currently no output until the end)</li> + </ul></small> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <small><b>*</b> only available for BFH authoritative zones</small> + + <div style="height: 1em"></div> + </div> +</div> + +<hr /> + +<div id="output-hidden" style="display: none;"> +<a name="output"></a> +<a href="#top"><button type="button" class="btn btn-light btn-sm float-right">↑</button></a><br /> +<b>Output</b><br /> +<pre> +<textarea id="output" readonly rows="25" style="background: #f1f1f1; width: 100%;"></textarea> +</pre> +</div> + +<div style="height: 1em"></div> + + + </div> + + </main><!-- /.container --> + + <footer class="footer py-5"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <a href="https://www.bfh.ch"><img src="/logo.svg" style="height: 112.5px" /></a><br /> + <br /> + </div> + <div class="col-md-3"> + <small> + <strong><i class="fa-fw fas fa-map-marker"></i> Address</strong><br /> + <a class="text-muted" href="https://www.openstreetmap.org/search?query=Dammweg 3%2C 3013 Bern">Berner Fachhochschule<br /> + IT-Services<br /> + Team Linux & Infrastructure Services<br /> + Dammweg 3, CH-3013 Bern</a><br /> + <br /> + </small> + </div> + <div class="col-md-3"> + <small> + <strong><i class="fa-fw fas fa-phone"></i> Phone</strong><br /> + <a class="text-muted" href="#">+41 31 848 48 48</a><br /> + <br /> + <strong><i class="fa-fw fas fa-envelope"></i> Email</strong><br /> + <a class="text-muted" href="mailto:bfh-linux-sysadmin@lists.bfh.science?subject=BFH.science:%20Feedback">bfh-linux-sysadmin@lists.bfh.science</a><br /> + <br /> + </small> + </div> + <div class="col-md-4"> + <small> + <br /> + <br /> + <br /> + <br /> + <i class="fa-fw fas fa-copyright"></i> <a class="text-muted" href="https://bfh.science/other/legal">2021</a> + + <a style="color: inherit;" href="https://bfh.science/other/legal" title="Legal Information"><i class="fa-fw fas fa-balance-scale"></i></a> <a class="text-muted" href="https://bfh.science/other/legal" title="Legal Information">Legal Information</a> + + <a class="a-hover-red" href="https://git.bfh.info" title="Made with Love and Git"><i class="fa-fw fas fa-heart"></i></a> <a class="text-muted" href="https://git.bfh.info" title="Made with Love and Git">Source Code</a><br /> + <br /> + </small> + </div> + </div> + </div> + </footer> + + <!-- Bootstrap core JS --> + <script src="/_static/popperjs/popper.min.js"></script> + <script src="/_static/bootstrap/js/bootstrap.min.js"></script> + + <!-- Custom scripts for this template --> + <script src="/_static/local/table.js"></script> + </body> +</html> diff --git a/web-tools/bin/tools-test.py b/web-tools/bin/tools-test.py new file mode 100755 index 0000000..e804409 --- /dev/null +++ b/web-tools/bin/tools-test.py @@ -0,0 +1,260 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Dependencies: +# sudo apt install iputils-ping traceroute whois nmap testssl.sh geoip-bin geoip-database knot-dnsutils + +from cgi import FieldStorage +from datetime import datetime +from ipaddress import ip_address +from os import getenv +from subprocess import Popen, PIPE +from sys import exit + +def filter_nameservers(servers, protocol): + nameservers= [] + + for server in servers: + name = server.rstrip().rstrip('.') + + if protocol == 'ipv6-only': + command = 'kdig -6' + options = ' -t AAAA +short -q ' + elif protocol == 'ipv4-only': + command = 'kdig -4' + options = ' -t A +short -q ' + else: + command = 'kdig' + options = ' +short -q ' + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + address = kdig.stdout.readline() + + if address: + nameservers.append(name) + + return nameservers + +def get_nameserver(name, protocol): + nameservers = [] + + if protocol == 'ipv6-only': + command = 'kdig -6' + elif protocol == 'ipv4-only': + command = 'kdig -4' + else: + command = 'kdig' + + options = ' -t NS +short -q ' + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + servers = kdig.stdout.readlines() + + count = 0 + while not servers and count < 10: + name = name.split('.') + del name[0] + name = '.'.join(name) + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + servers = kdig.stdout.readlines() + + count += 1 + + names = [] + for server in servers: + name = server.rstrip().decode('utf-8').rstrip('.') + names.append(name) + + nameservers = filter_nameservers(names, protocol) + return nameservers + +def run_command(command): + process = Popen(command, stdout=PIPE) + empty_lines = 0 + while True: + line = process.stdout.readline().rstrip() + if not line: + empty_lines = empty_lines + 1 + if empty_lines > 2: + break + else: + print() + else: + empty_lines = 0 + yield line.decode('utf-8') + +def main(): + form = FieldStorage() + + if form.getvalue("command"): + Command = form.getvalue("command").split()[0] + + if "target" in form: + Target = form.getvalue("target").split()[0] + + if "protocol" in form: + Protocol = form.getvalue("protocol").split()[0] + + if "query" in form: + Query = form.getvalue("query").split()[0] + + if Command and Protocol and Target: + print('Content-Type: text/html\n') + + Date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + if Command == 'kdig': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + + if Query == 'PTR': + arpa = ip_address(Target).reverse_pointer + + nameserver = get_nameserver(arpa, Protocol) + + protocol_passed = False + + for server in nameserver: + check_options = options + ' @' + server + ' -t ' + Query + ' -q ' + + command_line = (Command + ' +short' + check_options + arpa).split() + kdig = Popen(command_line, stdout=PIPE) + protocol_check = kdig.stdout.readline() + + if protocol_check: + protocol_passed = True + break + + if not protocol_passed: + print('IPv6-only query but no IPv6 enabled nameserver available for ' + Target + '\n\n') + print('--') + print('Run: ' + str(command_line)) + print('Date: ' + Date) + + exit(0) + + options = options + ' @' + server + ' -x ' + else: + nameserver = get_nameserver(Target, Protocol) + + protocol_passed = False + + for server in nameserver: + check_options = options + ' @' + server + ' -t ' + Query + ' -q ' + + command_line = (Command + ' +short' + check_options + Target).split() + kdig = Popen(command_line, stdout=PIPE) + protocol_check = kdig.stdout.readline() + + if protocol_check: + protocol_passed = True + break + + if not protocol_passed: + print('IPv6-only query but no IPv6 enabled nameserver available for ' + Target + '\n\n') + print('--') + print('Run: ' + str(command_line)) + print('Date: ' + Date) + + exit(0) + + options = options + ' @' + server + ' -t ' + Query + ' -q ' + elif Command == 'ping': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' -c3 ' + elif Command == 'traceroute': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' ' + elif Command == 'tcptraceroute': + Command = 'traceroute' + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' -T ' + elif Command == 'nmap': + if Protocol == 'ipv6-only': + options = ' -6' + else: + options = ' ' + #-O -T5 + elif Command == 'testssl': + options = ' --color 0 ' + elif Command == 'whois': + options = ' -H ' + else: + options = ' ' + + if Command == 'my-ip': + command_line = '' + + address = getenv('REMOTE_ADDR') + print('IP address: ' + address) + + # TODO: show reverse DNS + + if ':' in address: + print('IP version: IPv6') + process = Popen(['geoiplookup6', address], stdout=PIPE) + else: + print('IP version: IPv4') + process = Popen(['geoiplookup', address], stdout=PIPE) + + geoiplookup = process.stdout.readline().rstrip() + country = geoiplookup.decode('utf-8').split(':')[1] + print('Country:' + country + '\n\n') + elif Command == 'my-browser': + command_line = '' + print('User-Agent: ' + getenv('HTTP_USER_AGENT', 'n/a') + '\n\n') + else: + command_line = Command + options + Target + + for path in run_command(command_line.split()): + print(path) + + print('--') + print('Date: ' + Date) + + if command_line: + print('Run: ' + command_line) + + exit(0) + +if __name__ == '__main__': + main() diff --git a/web-tools/bin/tools.py b/web-tools/bin/tools.py new file mode 100755 index 0000000..bf1a067 --- /dev/null +++ b/web-tools/bin/tools.py @@ -0,0 +1,260 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Dependencies: +# sudo apt install iputils-ping traceroute whois nmap testssl.sh geoip-bin geoip-database knot-dnsutils + +from cgi import FieldStorage +from datetime import datetime +import ipaddress +from os import getenv +from subprocess import Popen, PIPE +from sys import exit + +def filter_nameservers(servers, protocol): + nameservers= [] + + for server in servers: + name = server.rstrip().rstrip('.') + + if protocol == 'ipv6-only': + command = 'kdig -6' + options = ' -t AAAA +short -q ' + elif protocol == 'ipv4-only': + command = 'kdig -4' + options = ' -t A +short -q ' + else: + command = 'kdig' + options = ' +short -q ' + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + address = kdig.stdout.readline() + + if address: + nameservers.append(name) + + return nameservers + +def get_nameserver(name, protocol): + nameservers = [] + + if protocol == 'ipv6-only': + command = 'kdig -6' + elif protocol == 'ipv4-only': + command = 'kdig -4' + else: + command = 'kdig' + + options = ' -t NS +short -q ' + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + servers = kdig.stdout.readlines() + + count = 0 + while not servers and count < 10: + name = name.split('.') + del name[0] + name = '.'.join(name) + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + servers = kdig.stdout.readlines() + + count += 1 + + names = [] + for server in servers: + name = server.rstrip().decode('utf-8').rstrip('.') + names.append(name) + + nameservers = filter_nameservers(names, protocol) + return nameservers + +def run_command(command): + process = Popen(command, stdout=PIPE) + empty_lines = 0 + while True: + line = process.stdout.readline().rstrip() + if not line: + empty_lines = empty_lines + 1 + if empty_lines > 2: + break + else: + print() + else: + empty_lines = 0 + yield line.decode('utf-8') + +def main(): + form = FieldStorage() + + if form.getvalue("command"): + Command = form.getvalue("command").split()[0] + + if "target" in form: + Target = form.getvalue("target").split()[0] + + if "protocol" in form: + Protocol = form.getvalue("protocol").split()[0] + + if "query" in form: + Query = form.getvalue("query").split()[0] + + if Command and Protocol and Target: + print('Content-Type: text/html\n') + + Date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + if Command == 'kdig': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + + if Query == 'PTR': + arpa = ipaddress.ip_address(Target).reverse_pointer + + nameserver = get_nameserver(arpa, Protocol) + + protocol_passed = False + + for server in nameserver: + check_options = options + ' @' + server + ' -t ' + Query + ' -q ' + + command_line = (Command + ' +short' + check_options + arpa).split() + kdig = Popen(command_line, stdout=PIPE) + protocol_check = kdig.stdout.readline() + + if protocol_check: + protocol_passed = True + break + + if not protocol_passed: + print('IPv6-only query but no IPv6 enabled nameserver available for ' + Target + '\n\n') + print('--') + print('Run: ' + str(command_line)) + print('Date: ' + Date) + + exit(0) + + options = options + ' @' + server + ' -x ' + else: + nameserver = get_nameserver(Target, Protocol) + + protocol_passed = False + + for server in nameserver: + check_options = options + ' @' + server + ' -t ' + Query + ' -q ' + + command_line = (Command + ' +short' + check_options + Target).split() + kdig = Popen(command_line, stdout=PIPE) + protocol_check = kdig.stdout.readline() + + if protocol_check: + protocol_passed = True + break + + if not protocol_passed: + print('IPv6-only query but no IPv6 enabled nameserver available for ' + Target + '\n\n') + print('--') + print('Run: ' + str(command_line)) + print('Date: ' + Date) + + exit(0) + + options = options + ' @' + server + ' -t ' + Query + ' -q ' + elif Command == 'ping': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' -c3 ' + elif Command == 'traceroute': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' ' + elif Command == 'tcptraceroute': + Command = 'traceroute' + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' -T ' + elif Command == 'nmap': + if Protocol == 'ipv6-only': + options = ' -6' + else: + options = ' ' + #-O -T5 + elif Command == 'testssl': + options = ' --color 0 ' + elif Command == 'whois': + options = ' -H ' + else: + options = ' ' + + if Command == 'my-ip': + command_line = '' + + ip_address = getenv('REMOTE_ADDR') + print('IP address: ' + ip_address) + + # TODO: show reverse DNS + + if ':' in ip_address: + print('IP version: IPv6') + process = Popen(['geoiplookup6', ip_address], stdout=PIPE) + else: + print('IP version: IPv4') + process = Popen(['geoiplookup', ip_address], stdout=PIPE) + + geoiplookup = process.stdout.readline().rstrip() + country = geoiplookup.decode('utf-8').split(':')[1] + print('Country:' + country + '\n\n') + elif Command == 'my-browser': + command_line = '' + print('User-Agent: ' + getenv('HTTP_USER_AGENT', 'n/a') + '\n\n') + else: + command_line = Command + options + Target + + for path in run_command(command_line.split()): + print(path) + + print('--') + print('Date: ' + Date) + + if command_line: + print('Run: ' + command_line) + + exit(0) + +if __name__ == '__main__': + main() |