Compare commits
46 Commits
Author | SHA1 | Date |
---|---|---|
B.J. Dweck | 46ab5fea97 | |
B.J. Dweck | 7197e9aa92 | |
B.J. Dweck | 2c6071ea79 | |
B.J. Dweck | 4ac90e7e77 | |
B.J. Dweck | 76e0c6e7a7 | |
B.J. Dweck | d3af567287 | |
B.J. Dweck | 0484e3b484 | |
B.J. Dweck | be4ce4a288 | |
B.J. Dweck | 7d764cb043 | |
B.J. Dweck | cd51f18eab | |
B.J. Dweck | 97f8bdd3ac | |
B.J. Dweck | 64b67b08cb | |
B.J. Dweck | 626c13cde2 | |
B.J. Dweck | 09ff9f6e86 | |
B.J. Dweck | 8bc211d413 | |
B.J. Dweck | 67758f6eb3 | |
B.J. Dweck | 43bece3c57 | |
B.J. Dweck | 16085fd594 | |
B.J. Dweck | 5a2ac0c3dc | |
B.J. Dweck | 26d4444137 | |
B.J. Dweck | 59ddc37cfd | |
B.J. Dweck | fe94fcc204 | |
B.J. Dweck | a8b1029ad2 | |
B.J. Dweck | 32ee0ffe55 | |
B.J. Dweck | f31e9e62d7 | |
B.J. Dweck | 05c9ae8d6e | |
B.J. Dweck | 64b9698010 | |
B.J. Dweck | d9e68d50fe | |
B.J. Dweck | 1c6da7a091 | |
B.J. Dweck | 609ccfbf27 | |
B.J. Dweck | a78cddfdb1 | |
B.J. Dweck | a38b6ee751 | |
B.J. Dweck | f3677ad45e | |
B.J. Dweck | ceb80569cb | |
B.J. Dweck | 72c6af328e | |
B.J. Dweck | 54b1fe79a9 | |
B.J. Dweck | 19df7d2d35 | |
B.J. Dweck | 1a4fceb89e | |
B.J. Dweck | fa3ad27146 | |
B.J. Dweck | 21d8dbe1d1 | |
B.J. Dweck | 4a54459eab | |
B.J. Dweck | 21665f976c | |
B.J. Dweck | a891f9bf51 | |
B.J. Dweck | fa24e56662 | |
B.J. Dweck | c94962e2f1 | |
B.J. Dweck | a9aca4da54 |
|
@ -1,2 +1,9 @@
|
|||
.vagrant
|
||||
build
|
||||
build
|
||||
build_deb
|
||||
venv
|
||||
/dist/
|
||||
/*.egg-info
|
||||
*.pyc
|
||||
__pycache__
|
||||
.idea
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Benjamin Dweck
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
26
README.md
26
README.md
|
@ -13,7 +13,21 @@ A TORch solution consists of 3 processes:
|
|||
* MQTT broker - Any MQTT broker, reachable via IPv4 or Tor, through TLS or insecure communications
|
||||
* `torch-subscriber` - Listens for and handles onion hostname publications
|
||||
|
||||
## Build Debian Package
|
||||
Easily launch a TORch Node monitor service using the [`torch-subscriber-docker`](https://git.rudefox.io/bj/torch-subscriber-docker) project
|
||||
|
||||
## Installation
|
||||
|
||||
### Install Package from Rudefox Debian Repo
|
||||
|
||||
1. [Add the Rudefox Repo](https://rudefox.io/repo/) as an `apt` source
|
||||
|
||||
2. Install the `torch-agent` package
|
||||
|
||||
```bash
|
||||
sudo apt install torch-agent
|
||||
```
|
||||
|
||||
### Build Debian Package from Source
|
||||
|
||||
If you don't already have a GPG key, generate one:
|
||||
|
||||
|
@ -21,11 +35,11 @@ If you don't already have a GPG key, generate one:
|
|||
gpg --full-generate-key
|
||||
```
|
||||
|
||||
Using the e-mail address you provided during GPG key generation, run `make-pkg.sh` to build a Debian package and install it
|
||||
Using the e-mail address you provided during GPG key generation, run `build-deb.sh` to build a Debian package and install it
|
||||
|
||||
```bash
|
||||
./make-pkg.sh john@doe.com
|
||||
apt update && apt install build/torch-agent_0.0.1-1_all.deb
|
||||
./build-deb.sh john@doe.com
|
||||
apt update && apt install build/torch-agent_0.0.6-1_all.deb
|
||||
```
|
||||
|
||||
This will:
|
||||
|
@ -45,7 +59,3 @@ The configuation directory can be specified by
|
|||
A fully configured example can be found [here](example)
|
||||
|
||||
See the sample [`torch.conf`](torch.conf) file for additional configuration options and details
|
||||
|
||||
## Roadmap
|
||||
|
||||
[ ] Utilize [dh_python3](https://www.debian.org/doc/manuals/debmake-doc/ch08.en.html#setup-py) in Debian package build
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ -z "${DEB_EMAIL}" ]]; then
|
||||
DEB_EMAIL="$1"
|
||||
DPKG_BUILD_OPTS=-k"$DEB_EMAIL"
|
||||
fi
|
||||
|
||||
if [[ -z "${DEB_EMAIL}" ]]; then
|
||||
DEB_EMAIL="none@none.com"
|
||||
DPKG_BUILD_OPTS="-us -uc"
|
||||
fi
|
||||
|
||||
TORCH_VERSION=$(git describe --tags --abbrev=0)
|
||||
PROJECT=torch-agent-$TORCH_VERSION
|
||||
|
||||
BUILD_DIR=dist
|
||||
DEB_DIR=$BUILD_DIR/$PROJECT
|
||||
|
||||
rm -rf "${BUILD_DIR:?}"
|
||||
mkdir -p "$DEB_DIR/src/etc/torch"
|
||||
cp -r debian "$DEB_DIR/"
|
||||
cp torch.conf "$DEB_DIR/src/etc/torch/"
|
||||
|
||||
pip3 install -r requirements.txt
|
||||
python3 setup.py sdist
|
||||
|
||||
cd $BUILD_DIR || exit
|
||||
tar -xzmf "$PROJECT.tar.gz"
|
||||
|
||||
cd "$PROJECT" || exit
|
||||
export USER
|
||||
USER=$(whoami)
|
||||
dh_make --createorig -e "$DEB_EMAIL" -s -y
|
||||
dpkg-buildpackage $DPKG_BUILD_OPTS
|
|
@ -1,6 +0,0 @@
|
|||
torch-agent for Debian
|
||||
---------------------
|
||||
|
||||
<possible notes regarding this package - if none, delete this file>
|
||||
|
||||
-- Benjamin Dweck <bjdweck@gmail.com> Tue, 06 Oct 2020 15:53:02 +0200
|
|
@ -1,10 +0,0 @@
|
|||
torch-agent for Debian
|
||||
---------------------
|
||||
|
||||
<this file describes information about the source package, see Debian policy
|
||||
manual section 4.14. You WILL either need to modify or delete this file>
|
||||
|
||||
|
||||
|
||||
-- Benjamin Dweck <bjdweck@gmail.com> Tue, 06 Oct 2020 15:53:02 +0200
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
torch-agent (0.0.1-1) unstable; urgency=medium
|
||||
torch-agent (0.0.6-1) stable; urgency=medium
|
||||
|
||||
* Initial release
|
||||
* Update
|
||||
|
||||
-- Benjamin Dweck <bjdweck@gmail.com> Tue, 06 Oct 2020 15:53:02 +0200
|
||||
-- Benjamin Dweck <bjdweck@gmail.com> Tue, 08 Oct 2020 19:46:22 +0200
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
11
|
||||
|
|
@ -2,15 +2,17 @@ Source: torch-agent
|
|||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Benjamin Dweck <bjdweck@gmail.com>
|
||||
Build-Depends: debhelper-compat (= 12)
|
||||
Build-Depends: debhelper (>=11~), dh-python, python3-all
|
||||
Standards-Version: 4.4.1
|
||||
Homepage: https://rudefox.io
|
||||
Homepage: https://git.rudefox.io/bj/torch-agent
|
||||
X-Python3-Version: >= 3.2
|
||||
#Vcs-Browser: https://salsa.debian.org/debian/torch-agent
|
||||
#Vcs-Git: https://salsa.debian.org/debian/torch-agent.git
|
||||
Vcs-Git: https://git.rudefox.io/bj/torch-agent.git
|
||||
|
||||
Package: torch-agent
|
||||
Architecture: all
|
||||
Depends: ssh, tor, python3-pip, ${misc:Depends}
|
||||
Multi-Arch: foreign
|
||||
Depends: ssh, tor, python3-pip, ${misc:Depends}, ${python3:Depends}
|
||||
Description: TORch is a solution for creating an SSH-via-Tor
|
||||
backdoor on a remote device as a means of fallback remote
|
||||
management and initial headless device configuration.
|
||||
management and initial headless device configuration.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: torch-agent
|
||||
Upstream-Contact: bjdweck@gmail.com
|
||||
Source: https://rudefox.io
|
||||
Source: https://git.rudefox.io/bj/torch-agent
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2020 Benjamin Dweck <bjdweck@gmail.com>
|
||||
|
@ -20,4 +20,4 @@ License: GPL-2+
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
torch-agent_0.0.1-1_all.deb net optional
|
||||
torch-agent_0.0.1-1_amd64.buildinfo net optional
|
|
@ -1,56 +0,0 @@
|
|||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" (C) Copyright 2020 Benjamin Dweck <bjdweck@gmail.com>,
|
||||
.\"
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH Torch-agent SECTION "October 6 2020"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
torch-agent \- program to do something
|
||||
.SH SYNOPSIS
|
||||
.B torch-agent
|
||||
.RI [ options ] " files" ...
|
||||
.br
|
||||
.B bar
|
||||
.RI [ options ] " files" ...
|
||||
.SH DESCRIPTION
|
||||
This manual page documents briefly the
|
||||
.B torch-agent
|
||||
and
|
||||
.B bar
|
||||
commands.
|
||||
.PP
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||
.\" respectively.
|
||||
\fBtorch-agent\fP is a program that...
|
||||
.SH OPTIONS
|
||||
These programs follow the usual GNU command line syntax, with long
|
||||
options starting with two dashes (`-').
|
||||
A summary of options is included below.
|
||||
For a complete description, see the Info files.
|
||||
.TP
|
||||
.B \-h, \-\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.B \-v, \-\-version
|
||||
Show version of program.
|
||||
.SH SEE ALSO
|
||||
.BR bar (1),
|
||||
.BR baz (1).
|
||||
.br
|
||||
The programs are documented fully by
|
||||
.IR "The Rise and Fall of a Fooish Bar" ,
|
||||
available via the Info system.
|
|
@ -1,154 +0,0 @@
|
|||
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
|
||||
|
||||
<!-- Process this file with docbook-to-man to generate an nroff manual
|
||||
page: `docbook-to-man manpage.sgml > manpage.1'. You may view
|
||||
the manual page with: `docbook-to-man manpage.sgml | nroff -man |
|
||||
less'. A typical entry in a Makefile or Makefile.am is:
|
||||
|
||||
manpage.1: manpage.sgml
|
||||
docbook-to-man $< > $@
|
||||
|
||||
|
||||
The docbook-to-man binary is found in the docbook-to-man package.
|
||||
Please remember that if you create the nroff version in one of the
|
||||
debian/rules file targets (such as build), you will need to include
|
||||
docbook-to-man in your Build-Depends control field.
|
||||
|
||||
-->
|
||||
|
||||
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
|
||||
<!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
|
||||
<!ENTITY dhsurname "<surname>SURNAME</surname>">
|
||||
<!-- Please adjust the date whenever revising the manpage. -->
|
||||
<!ENTITY dhdate "<date>October 6 2020</date>">
|
||||
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
|
||||
allowed: see man(7), man(1). -->
|
||||
<!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
|
||||
<!ENTITY dhemail "<email>bjdweck@gmail.com</email>">
|
||||
<!ENTITY dhusername "Benjamin Dweck">
|
||||
<!ENTITY dhucpackage "<refentrytitle>Torch-agent</refentrytitle>">
|
||||
<!ENTITY dhpackage "torch-agent">
|
||||
|
||||
<!ENTITY debian "<productname>Debian</productname>">
|
||||
<!ENTITY gnu "<acronym>GNU</acronym>">
|
||||
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
|
||||
]>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<address>
|
||||
&dhemail;
|
||||
</address>
|
||||
<author>
|
||||
&dhfirstname;
|
||||
&dhsurname;
|
||||
</author>
|
||||
<copyright>
|
||||
<year>2003</year>
|
||||
<holder>&dhusername;</holder>
|
||||
</copyright>
|
||||
&dhdate;
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
&dhucpackage;
|
||||
|
||||
&dhsection;
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>&dhpackage;</refname>
|
||||
|
||||
<refpurpose>program to do something</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>&dhpackage;</command>
|
||||
|
||||
<arg><option>-e <replaceable>this</replaceable></option></arg>
|
||||
|
||||
<arg><option>--example <replaceable>that</replaceable></option></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<title>DESCRIPTION</title>
|
||||
|
||||
<para>This manual page documents briefly the
|
||||
<command>&dhpackage;</command> and <command>bar</command>
|
||||
commands.</para>
|
||||
|
||||
<para>This manual page was written for the &debian; distribution
|
||||
because the original program does not have a manual page.
|
||||
Instead, it has documentation in the &gnu;
|
||||
<application>Info</application> format; see below.</para>
|
||||
|
||||
<para><command>&dhpackage;</command> is a program that...</para>
|
||||
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
|
||||
<para>These programs follow the usual &gnu; command line syntax,
|
||||
with long options starting with two dashes (`-'). A summary of
|
||||
options is included below. For a complete description, see the
|
||||
<application>Info</application> files.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>-h</option>
|
||||
<option>--help</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Show summary of options.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-v</option>
|
||||
<option>--version</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Show version of program.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>SEE ALSO</title>
|
||||
|
||||
<para>bar (1), baz (1).</para>
|
||||
|
||||
<para>The programs are documented fully by <citetitle>The Rise and
|
||||
Fall of a Fooish Bar</citetitle> available via the
|
||||
<application>Info</application> system.</para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>AUTHOR</title>
|
||||
|
||||
<para>This manual page was written by &dhusername; &dhemail; for
|
||||
the &debian; system (and may be used by others). Permission is
|
||||
granted to copy, distribute and/or modify this document under
|
||||
the terms of the &gnu; General Public License, Version 2 any
|
||||
later version published by the Free Software Foundation.
|
||||
</para>
|
||||
<para>
|
||||
On Debian systems, the complete text of the GNU General Public
|
||||
License can be found in /usr/share/common-licenses/GPL.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-omittag:t
|
||||
sgml-shorttag:t
|
||||
sgml-minimize-attributes:nil
|
||||
sgml-always-quote-attributes:t
|
||||
sgml-indent-step:2
|
||||
sgml-indent-data:t
|
||||
sgml-parent-document:nil
|
||||
sgml-default-dtd-file:nil
|
||||
sgml-exposed-tags:nil
|
||||
sgml-local-catalogs:nil
|
||||
sgml-local-ecat-files:nil
|
||||
End:
|
||||
-->
|
|
@ -1,291 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
|
||||
<!--
|
||||
|
||||
`xsltproc -''-nonet \
|
||||
-''-param man.charmap.use.subset "0" \
|
||||
-''-param make.year.ranges "1" \
|
||||
-''-param make.single.year.ranges "1" \
|
||||
/usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl \
|
||||
manpage.xml'
|
||||
|
||||
A manual page <package>.<section> will be generated. You may view the
|
||||
manual page with: nroff -man <package>.<section> | less'. A typical entry
|
||||
in a Makefile or Makefile.am is:
|
||||
|
||||
DB2MAN = /usr/share/sgml/docbook/stylesheet/xsl/docbook-xsl/manpages/docbook.xsl
|
||||
XP = xsltproc -''-nonet -''-param man.charmap.use.subset "0"
|
||||
|
||||
manpage.1: manpage.xml
|
||||
$(XP) $(DB2MAN) $<
|
||||
|
||||
The xsltproc binary is found in the xsltproc package. The XSL files are in
|
||||
docbook-xsl. A description of the parameters you can use can be found in the
|
||||
docbook-xsl-doc-* packages. Please remember that if you create the nroff
|
||||
version in one of the debian/rules file targets (such as build), you will need
|
||||
to include xsltproc and docbook-xsl in your Build-Depends control field.
|
||||
Alternatively use the xmlto command/package. That will also automatically
|
||||
pull in xsltproc and docbook-xsl.
|
||||
|
||||
Notes for using docbook2x: docbook2x-man does not automatically create the
|
||||
AUTHOR(S) and COPYRIGHT sections. In this case, please add them manually as
|
||||
<refsect1> ... </refsect1>.
|
||||
|
||||
To disable the automatic creation of the AUTHOR(S) and COPYRIGHT sections
|
||||
read /usr/share/doc/docbook-xsl/doc/manpages/authors.html. This file can be
|
||||
found in the docbook-xsl-doc-html package.
|
||||
|
||||
Validation can be done using: `xmllint -''-noout -''-valid manpage.xml`
|
||||
|
||||
General documentation about man-pages and man-page-formatting:
|
||||
man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
||||
|
||||
-->
|
||||
|
||||
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
|
||||
<!ENTITY dhfirstname "FIRSTNAME">
|
||||
<!ENTITY dhsurname "SURNAME">
|
||||
<!-- dhusername could also be set to "&dhfirstname; &dhsurname;". -->
|
||||
<!ENTITY dhusername "Benjamin Dweck">
|
||||
<!ENTITY dhemail "bjdweck@gmail.com">
|
||||
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
|
||||
allowed: see man(7), man(1) and
|
||||
http://www.tldp.org/HOWTO/Man-Page/q2.html. -->
|
||||
<!ENTITY dhsection "SECTION">
|
||||
<!-- TITLE should be something like "User commands" or similar (see
|
||||
http://www.tldp.org/HOWTO/Man-Page/q2.html). -->
|
||||
<!ENTITY dhtitle "torch-agent User Manual">
|
||||
<!ENTITY dhucpackage "Torch-agent">
|
||||
<!ENTITY dhpackage "torch-agent">
|
||||
]>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<title>&dhtitle;</title>
|
||||
<productname>&dhpackage;</productname>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>&dhfirstname;</firstname>
|
||||
<surname>&dhsurname;</surname>
|
||||
<contrib>Wrote this manpage for the Debian system.</contrib>
|
||||
<address>
|
||||
<email>&dhemail;</email>
|
||||
</address>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<copyright>
|
||||
<year>2007</year>
|
||||
<holder>&dhusername;</holder>
|
||||
</copyright>
|
||||
<legalnotice>
|
||||
<para>This manual page was written for the Debian system
|
||||
(and may be used by others).</para>
|
||||
<para>Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License,
|
||||
Version 2 or (at your option) any later version published by
|
||||
the Free Software Foundation.</para>
|
||||
<para>On Debian systems, the complete text of the GNU General Public
|
||||
License can be found in
|
||||
<filename>/usr/share/common-licenses/GPL</filename>.</para>
|
||||
</legalnotice>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>&dhucpackage;</refentrytitle>
|
||||
<manvolnum>&dhsection;</manvolnum>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>&dhpackage;</refname>
|
||||
<refpurpose>program to do something</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>&dhpackage;</command>
|
||||
<!-- These are several examples, how syntaxes could look -->
|
||||
<arg choice="plain"><option>-e <replaceable>this</replaceable></option></arg>
|
||||
<arg choice="opt"><option>--example=<parameter>that</parameter></option></arg>
|
||||
<arg choice="opt">
|
||||
<group choice="req">
|
||||
<arg choice="plain"><option>-e</option></arg>
|
||||
<arg choice="plain"><option>--example</option></arg>
|
||||
</group>
|
||||
<replaceable class="option">this</replaceable>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<group choice="req">
|
||||
<arg choice="plain"><option>-e</option></arg>
|
||||
<arg choice="plain"><option>--example</option></arg>
|
||||
</group>
|
||||
<group choice="req">
|
||||
<arg choice="plain"><replaceable>this</replaceable></arg>
|
||||
<arg choice="plain"><replaceable>that</replaceable></arg>
|
||||
</group>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>&dhpackage;</command>
|
||||
<!-- Normally the help and version options make the programs stop
|
||||
right after outputting the requested information. -->
|
||||
<group choice="opt">
|
||||
<arg choice="plain">
|
||||
<group choice="req">
|
||||
<arg choice="plain"><option>-h</option></arg>
|
||||
<arg choice="plain"><option>--help</option></arg>
|
||||
</group>
|
||||
</arg>
|
||||
<arg choice="plain">
|
||||
<group choice="req">
|
||||
<arg choice="plain"><option>-v</option></arg>
|
||||
<arg choice="plain"><option>--version</option></arg>
|
||||
</group>
|
||||
</arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
<refsect1 id="description">
|
||||
<title>DESCRIPTION</title>
|
||||
<para>This manual page documents briefly the
|
||||
<command>&dhpackage;</command> and <command>bar</command>
|
||||
commands.</para>
|
||||
<para>This manual page was written for the Debian distribution
|
||||
because the original program does not have a manual page.
|
||||
Instead, it has documentation in the GNU <citerefentry>
|
||||
<refentrytitle>info</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry> format; see below.</para>
|
||||
<para><command>&dhpackage;</command> is a program that...</para>
|
||||
</refsect1>
|
||||
<refsect1 id="options">
|
||||
<title>OPTIONS</title>
|
||||
<para>The program follows the usual GNU command line syntax,
|
||||
with long options starting with two dashes (`-'). A summary of
|
||||
options is included below. For a complete description, see the
|
||||
<citerefentry>
|
||||
<refentrytitle>info</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry> files.</para>
|
||||
<variablelist>
|
||||
<!-- Use the variablelist.term.separator and the
|
||||
variablelist.term.break.after parameters to
|
||||
control the term elements. -->
|
||||
<varlistentry>
|
||||
<term><option>-e <replaceable>this</replaceable></option></term>
|
||||
<term><option>--example=<replaceable>that</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>Does this and that.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-h</option></term>
|
||||
<term><option>--help</option></term>
|
||||
<listitem>
|
||||
<para>Show summary of options.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-v</option></term>
|
||||
<term><option>--version</option></term>
|
||||
<listitem>
|
||||
<para>Show version of program.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1 id="files">
|
||||
<title>FILES</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>/etc/foo.conf</filename></term>
|
||||
<listitem>
|
||||
<para>The system-wide configuration file to control the
|
||||
behaviour of <application>&dhpackage;</application>. See
|
||||
<citerefentry>
|
||||
<refentrytitle>foo.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry> for further details.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>${HOME}/.foo.conf</filename></term>
|
||||
<listitem>
|
||||
<para>The per-user configuration file to control the
|
||||
behaviour of <application>&dhpackage;</application>. See
|
||||
<citerefentry>
|
||||
<refentrytitle>foo.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry> for further details.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1 id="environment">
|
||||
<title>ENVIRONMENT</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><envar>FOO_CONF</envar></term>
|
||||
<listitem>
|
||||
<para>If used, the defined file is used as configuration
|
||||
file (see also <xref linkend="files"/>).</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1 id="diagnostics">
|
||||
<title>DIAGNOSTICS</title>
|
||||
<para>The following diagnostics may be issued
|
||||
on <filename class="devicefile">stderr</filename>:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errortext>Bad configuration file. Exiting.</errortext></term>
|
||||
<listitem>
|
||||
<para>The configuration file seems to contain a broken configuration
|
||||
line. Use the <option>--verbose</option> option, to get more info.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para><command>&dhpackage;</command> provides some return codes, that can
|
||||
be used in scripts:</para>
|
||||
<segmentedlist>
|
||||
<segtitle>Code</segtitle>
|
||||
<segtitle>Diagnostic</segtitle>
|
||||
<seglistitem>
|
||||
<seg><errorcode>0</errorcode></seg>
|
||||
<seg>Program exited successfully.</seg>
|
||||
</seglistitem>
|
||||
<seglistitem>
|
||||
<seg><errorcode>1</errorcode></seg>
|
||||
<seg>The configuration file seems to be broken.</seg>
|
||||
</seglistitem>
|
||||
</segmentedlist>
|
||||
</refsect1>
|
||||
<refsect1 id="bugs">
|
||||
<!-- Or use this section to tell about upstream BTS. -->
|
||||
<title>BUGS</title>
|
||||
<para>The program is currently limited to only work
|
||||
with the <package>foobar</package> library.</para>
|
||||
<para>The upstreams <acronym>BTS</acronym> can be found
|
||||
at <ulink url="http://bugzilla.foo.tld"/>.</para>
|
||||
</refsect1>
|
||||
<refsect1 id="see_also">
|
||||
<title>SEE ALSO</title>
|
||||
<!-- In alpabetical order. -->
|
||||
<para><citerefentry>
|
||||
<refentrytitle>bar</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>, <citerefentry>
|
||||
<refentrytitle>baz</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>, <citerefentry>
|
||||
<refentrytitle>foo.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry></para>
|
||||
<para>The programs are documented fully by <citetitle>The Rise and
|
||||
Fall of a Fooish Bar</citetitle> available via the <citerefentry>
|
||||
<refentrytitle>info</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry> system.</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
|
@ -42,22 +42,25 @@ configure_tor_controller() {
|
|||
fi
|
||||
|
||||
if [ $TORRC_CHANGED -eq 1 ]; then
|
||||
systemctl reload tor
|
||||
if [ -d "/run/systemd/system" ]; then
|
||||
systemctl reload tor
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
|
||||
if ! getent passwd $USER >/dev/null ; then
|
||||
useradd -r -g $GROUP $USER
|
||||
fi
|
||||
if ! getent passwd $USER >/dev/null ; then
|
||||
useradd -r -g $GROUP $USER
|
||||
fi
|
||||
|
||||
chown $USER /etc/torch
|
||||
chown $USER /etc/torch/torch.conf
|
||||
chown $USER /usr/share/torch-agent/torch-agent.py
|
||||
sudo -H pip3 install 'paho-mqtt>=1.5.1'
|
||||
|
||||
configure_tor_controller
|
||||
chown $USER /etc/torch
|
||||
chown $USER /etc/torch/torch.conf
|
||||
|
||||
configure_tor_controller
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
|
|
|
@ -23,7 +23,7 @@ USER="torch"
|
|||
case "$1" in
|
||||
purge|abort-install)
|
||||
rm -rf /etc/torch
|
||||
rm -f /usr/share/torch-agent/torch-agent.py
|
||||
|
||||
if [ -x "$(command -v deluser)" ]; then
|
||||
deluser --quiet --system $USER > /dev/null || true
|
||||
else
|
||||
|
|
|
@ -16,10 +16,7 @@ set -e
|
|||
case "$1" in
|
||||
install|upgrade)
|
||||
|
||||
sudo -H pip3 install stem paho-mqtt PySocks
|
||||
|
||||
mkdir -p /etc/torch
|
||||
mkdir -p /usr/share/torch-agent
|
||||
;;
|
||||
|
||||
abort-upgrade)
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#!/bin/sh
|
||||
# prerm script for torch-agent
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <prerm> `remove'
|
||||
# * <old-prerm> `upgrade' <new-version>
|
||||
# * <new-prerm> `failed-upgrade' <old-version>
|
||||
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
|
||||
# * <deconfigured's-prerm> `deconfigure' `in-favour'
|
||||
# <package-being-installed> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see https://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
;;
|
||||
|
||||
failed-upgrade)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "prerm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
|
@ -0,0 +1 @@
|
|||
OthermoduleName python-othermodule; PEP386
|
|
@ -13,9 +13,11 @@
|
|||
# package maintainers to append LDFLAGS
|
||||
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
|
||||
export PYBUILD_NAME=torch-agent
|
||||
export PYBUILD_SYSTEM=distutils
|
||||
|
||||
%:
|
||||
dh $@
|
||||
dh $@ --with python3 --buildsystem=pybuild
|
||||
|
||||
override_dh_installsystemd:
|
||||
dh_installsystemd --no-start --no-enable
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# For more information on what jobs are run see:
|
||||
# https://salsa.debian.org/salsa-ci-team/pipeline
|
||||
#
|
||||
# To enable the jobs, go to your repository (at salsa.debian.org)
|
||||
# and click over Settings > CI/CD > Expand (in General pipelines).
|
||||
# In "Custom CI config path" write debian/salsa-ci.yml and click
|
||||
# in "Save Changes". The CI tests will run after the next commit.
|
||||
---
|
||||
include:
|
||||
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
|
||||
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
|
|
@ -1,2 +0,0 @@
|
|||
src/usr/share/torch-agent/torch-agent.py
|
||||
src/etc/torch/torch.conf
|
|
@ -1,19 +0,0 @@
|
|||
[tor]
|
||||
ProxyPort = 9050
|
||||
ControllerPort = 9051
|
||||
|
||||
[ssh]
|
||||
Port = 22
|
||||
|
||||
[mqtt]
|
||||
BrokerHost = mqtt.example.com # OR example1i3uyrbfoi3fi.onion
|
||||
BrokerPort = 1883
|
||||
ClientID = my-client
|
||||
Topic = example/topic
|
||||
|
||||
### Options for Using TLS
|
||||
|
||||
#RequireCertificate = true
|
||||
#CaFile = ca.crt
|
||||
#CertFile = client.crt
|
||||
#KeyFile = client.key
|
|
@ -1,98 +0,0 @@
|
|||
from stem.control import Controller
|
||||
import stem.connection
|
||||
import paho.mqtt.client as mqtt
|
||||
import ssl
|
||||
import socks
|
||||
import socket
|
||||
import json
|
||||
import configparser
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from os import environ
|
||||
|
||||
parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT')
|
||||
|
||||
parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch',
|
||||
help='configuration directory (default: /etc/torch)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
configPath = args.configPath
|
||||
|
||||
if "TORCH_CONFIG_DIR" in environ:
|
||||
configPath = environ.get("TORCH_CONFIG_DIR")
|
||||
|
||||
if not configPath.endswith("/"):
|
||||
configPath = configPath + "/"
|
||||
|
||||
print("Using torch configuration path: " + configPath)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(configPath + "torch.conf")
|
||||
|
||||
torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050)
|
||||
torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051)
|
||||
|
||||
sshPort = config['ssh'].getint('Port', fallback = 22)
|
||||
|
||||
mqttConfig = config['mqtt']
|
||||
mqttBrokerHost = mqttConfig.get('BrokerHost', fallback = "localhost")
|
||||
mqttBrokerPort = mqttConfig.getint('BrokerPort', fallback = 1883)
|
||||
clientID = mqttConfig.get('ClientID', fallback = socket.gethostname())
|
||||
mqttTopic = mqttConfig.get('Topic', fallback = "torch/%s/onion_url" % (clientID))
|
||||
|
||||
mqttRequireCertificate = mqttConfig.getboolean(
|
||||
'RequireCertificate',
|
||||
fallback = False)
|
||||
|
||||
mqttCaFile = configPath + mqttConfig.get('CaFile')
|
||||
mqttCertFile = configPath + mqttConfig.get('CertFile')
|
||||
mqttKeyFile = configPath + mqttConfig.get('KeyFile')
|
||||
|
||||
with Controller.from_port(port = torControllerPort) as controller:
|
||||
|
||||
protocolInfo = stem.connection.get_protocolinfo(controller)
|
||||
|
||||
stem.connection.authenticate_safecookie(
|
||||
controller,
|
||||
protocolInfo.cookie_path)
|
||||
|
||||
print("Connected to Tor on port %s" % (torControllerPort))
|
||||
|
||||
service = controller.create_ephemeral_hidden_service(
|
||||
sshPort,
|
||||
detached = True)
|
||||
|
||||
onionAddress = "%s.onion" % (service.service_id)
|
||||
|
||||
print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress))
|
||||
|
||||
payload = {
|
||||
'clientId': clientID,
|
||||
'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),
|
||||
'onionAddress': onionAddress,
|
||||
'sshPort': sshPort
|
||||
}
|
||||
|
||||
client = mqtt.Client()
|
||||
protocol = "mqtt"
|
||||
|
||||
if mqttRequireCertificate:
|
||||
client.tls_set(
|
||||
ca_certs = mqttCaFile,
|
||||
certfile = mqttCertFile,
|
||||
keyfile = mqttKeyFile,
|
||||
cert_reqs=ssl.CERT_REQUIRED)
|
||||
protocol = "mqtts"
|
||||
|
||||
if mqttBrokerHost.endswith(".onion"):
|
||||
client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort)
|
||||
client.tls_insecure_set(True)
|
||||
|
||||
client.connect(mqttBrokerHost, mqttBrokerPort, 60)
|
||||
client.publish(mqttTopic, json.dumps(payload))
|
||||
print("Connected to MQTT Broker at %s://%s:%s/%s" % (protocol, mqttBrokerHost, mqttBrokerPort, mqttTopic))
|
||||
print("Published payload: " + json.dumps(payload))
|
||||
|
||||
client.disconnect()
|
||||
print("Disconnected from MQTT Broker")
|
|
@ -1,2 +0,0 @@
|
|||
README.Debian
|
||||
README.source
|
|
@ -1,4 +0,0 @@
|
|||
#
|
||||
# Regular cron jobs for the torch-agent package
|
||||
#
|
||||
0 4 * * * root [ -x /usr/bin/torch-agent_maintenance ] && /usr/bin/torch-agent_maintenance
|
|
@ -1 +0,0 @@
|
|||
dh_installsystemd
|
|
@ -1,20 +0,0 @@
|
|||
Document: torch-agent
|
||||
Title: Debian torch-agent Manual
|
||||
Author: <insert document author here>
|
||||
Abstract: This manual describes what torch-agent is
|
||||
and how it can be used to
|
||||
manage online manuals on Debian systems.
|
||||
Section: unknown
|
||||
|
||||
Format: debiandoc-sgml
|
||||
Files: /usr/share/doc/torch-agent/torch-agent.sgml.gz
|
||||
|
||||
Format: postscript
|
||||
Files: /usr/share/doc/torch-agent/torch-agent.ps.gz
|
||||
|
||||
Format: text
|
||||
Files: /usr/share/doc/torch-agent/torch-agent.text.gz
|
||||
|
||||
Format: HTML
|
||||
Index: /usr/share/doc/torch-agent/html/index.html
|
||||
Files: /usr/share/doc/torch-agent/html/*.html
|
|
@ -1,2 +1 @@
|
|||
src/usr/share/torch-agent /usr/share/
|
||||
src/etc/torch /etc/
|
||||
src/etc/torch /etc/
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# Automatically added by dh_installsystemd/12.10ubuntu1
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_installsystemd/12.10ubuntu1
|
||||
if [ "$1" = "remove" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper mask 'torch-agent.service' >/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "purge" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper purge 'torch-agent.service' >/dev/null || true
|
||||
deb-systemd-helper unmask 'torch-agent.service' >/dev/null || true
|
||||
fi
|
||||
fi
|
||||
# End automatically added section
|
|
@ -5,9 +5,9 @@ Requires=tor.service ssh.service
|
|||
|
||||
[Service]
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
ExecStart=/usr/bin/python3 /usr/share/torch-agent/torch-agent.py
|
||||
ExecStart=/usr/bin/torch-agent
|
||||
User=torch
|
||||
Group=debian-tor
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target ssh.service tor.service
|
||||
WantedBy=multi-user.target ssh.service tor.service
|
|
@ -1,38 +0,0 @@
|
|||
# Example watch control file for uscan
|
||||
# Rename this file to "watch" and then you can run the "uscan" command
|
||||
# to check for upstream updates and more.
|
||||
# See uscan(1) for format
|
||||
|
||||
# Compulsory line, this is a version 4 file
|
||||
version=4
|
||||
|
||||
# PGP signature mangle, so foo.tar.gz has foo.tar.gz.sig
|
||||
#opts="pgpsigurlmangle=s%$%.sig%"
|
||||
|
||||
# HTTP site (basic)
|
||||
#http://example.com/downloads.html \
|
||||
# files/torch-agent-([\d\.]+)\.tar\.gz debian uupdate
|
||||
|
||||
# Uncomment to examine an FTP server
|
||||
#ftp://ftp.example.com/pub/torch-agent-(.*)\.tar\.gz debian uupdate
|
||||
|
||||
# SourceForge hosted projects
|
||||
# http://sf.net/torch-agent/ torch-agent-(.*)\.tar\.gz debian uupdate
|
||||
|
||||
# GitHub hosted projects
|
||||
#opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%<project>-$1.tar.gz%" \
|
||||
# https://github.com/<user>/torch-agent/tags \
|
||||
# (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
|
||||
|
||||
# PyPI
|
||||
# https://pypi.debian.net/torch-agent/torch-agent-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
|
||||
|
||||
# Direct Git
|
||||
# opts="mode=git" http://git.example.com/torch-agent.git \
|
||||
# refs/tags/v([\d\.]+) debian uupdate
|
||||
|
||||
|
||||
|
||||
|
||||
# Uncomment to find new files on GooglePages
|
||||
# http://example.googlepages.com/foo.html torch-agent-(.*)\.tar\.gz
|
|
@ -0,0 +1,13 @@
|
|||
FROM ubuntu
|
||||
|
||||
RUN apt update && \
|
||||
apt install -y sudo ssh tor curl python3-all
|
||||
|
||||
COPY dist/torch-agent_*_all.deb .
|
||||
RUN apt install -y ./torch-agent_*_all.deb
|
||||
|
||||
COPY docker-tor/torch-agent.wrapper.sh /usr/bin/torch-agent.wrapper.sh
|
||||
|
||||
VOLUME [ "/etc/torch" ]
|
||||
|
||||
ENTRYPOINT [ "torch-agent.wrapper.sh" ]
|
|
@ -0,0 +1,29 @@
|
|||
# Tor Test Harness for TORch Agent
|
||||
|
||||
This is a Docker container for running the current development version of TORch Agent in an environment with a local Tor Proxy (without having to install and configure Tor on the development machine itself)
|
||||
|
||||
## Preparation
|
||||
|
||||
1. Build a Debian package from the current development version of TORch Agent
|
||||
|
||||
```bash
|
||||
python -m venv venv && source venv/bin/activate
|
||||
pip3 install -r requirements.txt
|
||||
./build-deb.sh
|
||||
```
|
||||
|
||||
2. Build the Docker image
|
||||
|
||||
```bash
|
||||
docker build -f docker-tor/Dockerfile -t torch-agent .
|
||||
```
|
||||
|
||||
3. Configure `torch-agent` by editing [`agent-conf/torch.conf`](./agent-conf/torch.conf)
|
||||
|
||||
* Be sure to update the onion hostname of the broker with the one you wish to test with
|
||||
|
||||
4. Launch the Docker container
|
||||
|
||||
```bash
|
||||
docker run -it --rm -v "$(pwd)/docker-tor/agent-conf:/etc/torch" torch-agent
|
||||
```
|
|
@ -0,0 +1,21 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDhDCCAmwCFFfe134gzLKm3ieNbeoxCvOhwsGxMA0GCSqGSIb3DQEBCwUAMIGE
|
||||
MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRUw
|
||||
EwYDVQQKDAxFeGFtcGxlIEluYy4xHDAaBgNVBAMME2NhLm1xdHQuZXhhbXBsZS5j
|
||||
b20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMB4XDTIwMTAwNjEx
|
||||
MDQxMVoXDTMwMTAwNDExMDQxMVoweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5Z
|
||||
MREwDwYDVQQHDAhOZXcgWW9yazEVMBMGA1UECgwMRXhhbXBsZSBJbmMuMRAwDgYD
|
||||
VQQDDAd2YWdyYW50MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALBR3WYBUoSM9taDBWn8MSU3
|
||||
WW7z9EmutaWRKlNCf8rAVXrEGf3shtBb6MWdRjAKHcBDZaTtmW6o0XoXkKdGeWcm
|
||||
6X0o4TwaROPE7HR8OtKsmPTxQ09gKfkwB+sb8+fIPrKq6VLWiSJqvc6RbZvoKXIa
|
||||
WU/BV4q3HG9MvFB2AMNx9pmzLeeP/m323pAEU28oR/kGvuDJHSLO3cNd1U5ZKFFt
|
||||
J1hHYugKM3uHlyQ44ozu6l2AexGgIYjA5/y1D/RuWaybdpppLS3RerhKDrvTkwWD
|
||||
UALgTdxHnIT90NFCtGsZTzwmbqs/ibq1NtkHGiS0tGhJjftIiPJZfuNArVsoYF0C
|
||||
AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeOEgOA8dJZGo/bT+2vnKm7VnJYrNgAax
|
||||
B/X2kG3vLiayFgPYarQq8AjlqQCr8Dm1EqbUtnAhzSbQTX+v3oQBd7sRdlwfTYKa
|
||||
bFEjhMeXhBgp/bWobq9FcwAL02wsAZh/gcbHAVrIwWmb42sbHTmrWY2jgJbX65jg
|
||||
ameIn9p1j2CSJnC4Ju3B+btaCmksHI6uhuJVef/+pL53hs1z5MfehNvJaBkUzsya
|
||||
nYAiCvrEQIzKlxROdBApZeQs0WFv0ktu6itzA3YsCMct1p3TNGwDUZ+cQqkTPhkB
|
||||
KNT0VcmDNdavD59WsEfrgZe5/DXY+Q1yHzGmaq70y0U6SgTfOsslmQ==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAsFHdZgFShIz21oMFafwxJTdZbvP0Sa61pZEqU0J/ysBVesQZ
|
||||
/eyG0FvoxZ1GMAodwENlpO2ZbqjReheQp0Z5ZybpfSjhPBpE48TsdHw60qyY9PFD
|
||||
T2Ap+TAH6xvz58g+sqrpUtaJImq9zpFtm+gpchpZT8FXirccb0y8UHYAw3H2mbMt
|
||||
54/+bfbekARTbyhH+Qa+4MkdIs7dw13VTlkoUW0nWEdi6Aoze4eXJDjijO7qXYB7
|
||||
EaAhiMDn/LUP9G5ZrJt2mmktLdF6uEoOu9OTBYNQAuBN3EechP3Q0UK0axlPPCZu
|
||||
qz+JurU22QcaJLS0aEmN+0iI8ll+40CtWyhgXQIDAQABAoIBAQCYYtiHbYMk3jQD
|
||||
p49JT1YmRRT9aMhr2hxR8Ql0lheeYuY9yThxljfZ4mVmTYw4vrWB0n4JsfQWiL8q
|
||||
1y0E9Uq9lQrdSjSH3mhFto9qCWhJZjR4FgBHnOQJ4rIlR65gV1eg0UgAeTxiS4Cq
|
||||
BFSIF3mijRU9ces4DxP7OYXTwHjecLQXWzsENhlcowTCYOfxLM/8YvVRCv2cxPJh
|
||||
/TL3qn1LD5/15lUb58+SqNAOREGACB+YG6rFShvUrxkq3ShtZdPUOzM5z+9xS8yO
|
||||
Uh2aZDmxtMB6GnYbQNhfM274i71aVhf0++7s8VsiVo3C61+qKIYcX0LK8t2PnQ1H
|
||||
cFn20hKhAoGBANfyLB5T+nZUGBysZSe76SoZUFWM0OsLixLq0+CqHvnTmIVMLQpv
|
||||
k8RV2/g7rKCcaKghSENI2gwWy+EDfVGi/nGc+uJ+n4FX92F98MmmzFvuQXOp1AuY
|
||||
Qvqr2XquFu5B6Jz5aOniOMHHSRl9JmZOLc+rs7COH7s/o5OPBT+1OpHJAoGBANEG
|
||||
HBnAuxZ0XJtB7TvA9wW3GCRidCisRH8rG0cN4dE3UuCC+DQq1AV03NwM6pycwz15
|
||||
ljpkb+WtbE6iKG3sfj3vWhwkakcEnJKXGCVbKmMXI0L2sMnQB4bJ4TtXGDRJlLKg
|
||||
XuwBsEmN8pM8IqRmnSpTrVbpCo4vZ/29c8l9+YP1AoGAcgIBGOHtUZuEP18k6J1k
|
||||
tD05FHGLuwwVGJ+xzOMEB5GW7IkTHndZ5EYQJDYdJY5uEpW/uQY1WDyQ1vMornkH
|
||||
LKRcMEf5nif7CxWaklvleIOJOq9mq9hvRDiGUSaoJJHXZUioAxLUNDoqdbKFG24a
|
||||
8ZENBSGDzzACBF11v/TGP0ECgYEAp+WCeOUo4jaBlGx2RIMRaNPTXpZ+u5T0SDm1
|
||||
5XMvKkCIH7LT8ANe3ysppM/zO+1nnl+l3i2C/Dg7QUZbt0A5f0JdXTGa9IStx8n6
|
||||
KTd7arDRMB67jr+86/YJJwMkfAuGl5zd4jDRC6Qrbzzkjq2mHLOuDpuOUPufSl/9
|
||||
O6Im5GkCgYA4zFE3ztSV6nq5EH3A7VmAsLiyRXBJfOlLXIBApv46/t4ivS4C3Esu
|
||||
8LR+Vvx2XLWkpkrm9kR1wIutNx6x1pRkSGDKyRXn5+cU4A2Lw9y2BbwDhj+WiHkM
|
||||
zCuL+8l2px2f3K1YPE3oGWHZZJScDwa03yjVzrSPDr766XBtH7W4vg==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,23 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIID6zCCAtOgAwIBAgIUQJye5MbZVMpOpu87TmmlN/KOBj0wDQYJKoZIhvcNAQEL
|
||||
BQAwgYQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTERMA8GA1UEBwwITmV3IFlv
|
||||
cmsxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEcMBoGA1UEAwwTY2EubXF0dC5leGFt
|
||||
cGxlLmNvbTEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20wHhcNMjAx
|
||||
MDA2MTA1OTE4WhcNMzAxMDA0MTA1OTE4WjCBhDELMAkGA1UEBhMCVVMxCzAJBgNV
|
||||
BAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9yazEVMBMGA1UECgwMRXhhbXBsZSBJbmMu
|
||||
MRwwGgYDVQQDDBNjYS5tcXR0LmV4YW1wbGUuY29tMSAwHgYJKoZIhvcNAQkBFhFh
|
||||
ZG1pbkBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
ALVndltaj3SX1zuJB0F5woIMUZCHopkgiO027/qE10IgM6SN4lFhR7wR0B/9PXrf
|
||||
zn1xTC63w9xd3GbnlJvcWhWbh/m1t2Qx2mIvOmoELY8wlY6/V6NzjSgju7mZi0u6
|
||||
aitU+LXINNuGS+JhVpc54QQ8M9o0jKlnNGnEmPjv6uhbNXx3f8lw3eqSr1ZqmpGd
|
||||
UQVYKsNYBVzSqsnh/sn/KnGYn/nmpsKRWeLhoslJ3zDjaM/Y4NYol11nWFIPYCk5
|
||||
7rzzxES/WdWLLnZ2W59YCT54YOGFqXE7oYgReD+Og2YwnGVQQpDcvb2HyIZL/2pa
|
||||
oC6avMo/eC8HbSxwUKCnj1cCAwEAAaNTMFEwHQYDVR0OBBYEFEC8a9l0rpIdUqCS
|
||||
i4NJwXlqUoLeMB8GA1UdIwQYMBaAFEC8a9l0rpIdUqCSi4NJwXlqUoLeMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGzxJWZdVozskr5yie2uetpL
|
||||
aAReCaHEdWudRN3wVW1Dpm2sE23x4VFiJ+Uow9k21GgtGUsAIFqRgb3/QO+ipODC
|
||||
GRwZmVopkuOaHfCz+tO8xqjvGHCidhhhNFdR9uVkWHoPKsQsvap0SSk12KMtFBRo
|
||||
3rmeQwPP4qEPFEwc2U0hCUMsIUvMSt3KrA/j+aMRzOXU7QIMFbcYEF1IaGJz1RMh
|
||||
h1VCXaUlL2liVTWU4XgudB8rMOuETec7un9hzoBVOWHxXdRrGPaoN4+zWiLRCDXO
|
||||
6wapOhkmTOXuZY/NcMMwTmdJKTEQBD6XIQamv91Ne2bT89LHpcp1LjbaCz+UAxg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,16 @@
|
|||
[tor]
|
||||
ControllerPort = 9051
|
||||
|
||||
[ssh]
|
||||
Port = 22
|
||||
|
||||
[mqtt]
|
||||
BrokerHost = wmzin3o2dvd4h2iu4mrf4zqbvgscgi27kd5afzvhgchghjdpqk7cmaqd.onion
|
||||
BrokerPort = 1883
|
||||
ClientID = myagent
|
||||
Topic = torch/myagent/wake
|
||||
RequireCertificate = false
|
||||
CaFile = ca.crt
|
||||
CertFile = agent.crt
|
||||
KeyFile = agent.key
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
tor &
|
||||
|
||||
while ! curl -s --socks5 127.0.0.1:9050 'https://check.torproject.org/' | grep -qm1 Congratulations
|
||||
do
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
torch-agent $1 $2 $3 $4
|
|
@ -35,19 +35,10 @@ In a separate terminal window, run the subscriber:
|
|||
|
||||
#### Run TORch Agent in Vagrant
|
||||
|
||||
[Build](..) the latest source into a Debian package and copy it to `example/`
|
||||
|
||||
```bash
|
||||
cd ..
|
||||
./make-pkg.sh john@doe.com
|
||||
cp -f build/torch-agent_0.0.1-1_all.deb example/
|
||||
cd example
|
||||
```
|
||||
|
||||
Run the Vagrant box in a third terminal window:
|
||||
|
||||
```bash
|
||||
vagrant up
|
||||
```
|
||||
|
||||
You should see that the broker received a connection from the Vagrant box at boot up and the subscriber received the onion hostname. You can use a local `tor` proxy to connect to the vagrant box using SSH and the onion hostname.
|
||||
You should see that the broker received a connection from the Vagrant box at boot up and the subscriber received the onion hostname. You can use a local `tor` proxy to connect to the vagrant box using SSH and the onion hostname.
|
||||
|
|
|
@ -64,17 +64,19 @@ Vagrant.configure("2") do |config|
|
|||
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
|
||||
# documentation for more information about their specific syntax and use.
|
||||
|
||||
config.vm.provision "file", source: "torch-agent_0.0.1-1_all.deb", destination: "~/"
|
||||
config.vm.provision "file", source: "agent-config", destination: "~/torch-conf"
|
||||
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
|
||||
sudo -- sh -c "echo '10.0.2.2 mqtt.example.com' >> /etc/hosts"
|
||||
|
||||
|
||||
sudo -- sh -c "echo '10.0.2.2 mqtt.example.com' >> /etc/hosts"
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y ./torch-agent_0.0.1-1_all.deb
|
||||
|
||||
sudo cp -f torch-conf/* /etc/torch/
|
||||
wget -qO - https://rudefox.io/repo/gpg | sudo apt-key add
|
||||
sudo add-apt-repository "deb https://repo.rudefox.io/repository/apt-release focal main"
|
||||
sudo apt update
|
||||
sudo apt install -y torch-agent
|
||||
|
||||
sudo cp -f torch-conf/* /etc/torch/
|
||||
sudo chown -R torch /etc/torch
|
||||
|
||||
sudo systemctl enable torch-agent
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
listener 8883
|
||||
websockets_log_level 9
|
||||
connection_messages true
|
||||
log_type all
|
||||
websockets_log_level 9
|
||||
|
||||
listener 1883
|
||||
cafile /mosquitto/config/ca.crt
|
||||
#keyfile /mosquitto/config/mqtt.example.com.key
|
||||
#certfile /mosquitto/config/mqtt.example.com.crt
|
||||
require_certificate true
|
||||
use_identity_as_username true
|
||||
|
||||
listener 8883
|
||||
cafile /mosquitto/config/ca.crt
|
||||
keyfile /mosquitto/config/mqtt.example.com.key
|
||||
certfile /mosquitto/config/mqtt.example.com.crt
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
docker run -it --rm --user $(echo $UID) --name mosquitto -p 8883:8883 -v $(pwd)/broker-config:/mosquitto/config eclipse-mosquitto
|
||||
docker run -it --rm --user $(echo $UID) --name mosquitto -p 8883:8883 -p 1883:1883 -v $(pwd)/broker-config:/mosquitto/config eclipse-mosquitto
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
mosquitto_sub -L mqtts://mqtt.example.com/it/torch/\+/ssh_onion --cafile subscriber-config/ca.crt --key subscriber-config/subscriber.key --cert subscriber-config/subscriber.crt
|
||||
mosquitto_sub -L mqtts://mqtt.example.com/torch/\+/onion_url --cafile subscriber-config/ca.crt --key subscriber-config/subscriber.key --cert subscriber-config/subscriber.crt
|
||||
|
|
Binary file not shown.
34
make-pkg.sh
34
make-pkg.sh
|
@ -1,34 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ -z "${DEBEMAIL}" ]]; then
|
||||
DEBEMAIL="$1"
|
||||
fi
|
||||
|
||||
if [[ -z "${DEBEMAIL}" ]]; then
|
||||
echo "E-mail address required for packaging signing with gpg key!"
|
||||
echo "Usage: ./make-pkg.sh EMAIL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TORCH_VERSION=$(git describe --tags)
|
||||
DEBIAN_PKG=torch-agent-$TORCH_VERSION
|
||||
PKG_ROOT=build/$DEBIAN_PKG
|
||||
|
||||
rf -rf $PKG_ROOT
|
||||
|
||||
mkdir -p $PKG_ROOT
|
||||
cp -r debian $PKG_ROOT
|
||||
|
||||
mkdir -p $PKG_ROOT/src/etc/torch
|
||||
cp torch.conf $PKG_ROOT/src/etc/torch/
|
||||
|
||||
mkdir -p $PKG_ROOT/src/usr/share/torch-agent
|
||||
cp torch-agent.py $PKG_ROOT/src/usr/share/torch-agent/
|
||||
|
||||
cp torch-agent.service $PKG_ROOT/debian/
|
||||
|
||||
cd $PKG_ROOT
|
||||
|
||||
export USER=`whoami`
|
||||
dh_make --createorig -e $DEBEMAIL -s -y
|
||||
dpkg-buildpackage -k$DEBEMAIL
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
USERNAME=$1
|
||||
PASSWORD=$2
|
||||
VERSION=$3
|
||||
|
||||
curl -u "$USERNAME:$PASSWORD" -H "Content-Type: multipart/form-data" --data-binary "@dist/torch-agent_${VERSION}-1_all.deb" "https://repo.rudefox.io/repository/apt-release/"
|
|
@ -0,0 +1,3 @@
|
|||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
|
@ -0,0 +1,6 @@
|
|||
pip~=20.2.4
|
||||
setuptools~=50.3.2
|
||||
stdeb3~=0.9.0.post2
|
||||
paho-mqtt~=1.5.1
|
||||
stem>=1.8.0
|
||||
PySocks
|
|
@ -0,0 +1,25 @@
|
|||
[metadata]
|
||||
name = torch-agent
|
||||
version = attr: torch_agent.__version__
|
||||
author = Benjamin Dweck
|
||||
author_email = bjdweck@gmail.com
|
||||
description = TORch: Illuminate the Way to your Node
|
||||
url = https://git.rudefox.io/bj/torch-agent
|
||||
classifiers =
|
||||
Programming Language :: Python :: 3
|
||||
License :: OSI Approved :: MIT License
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
install_requires =
|
||||
paho-mqtt~=1.5.1
|
||||
setuptools~=50.3.1
|
||||
pip~=20.2.3
|
||||
stem
|
||||
PySocks
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts = torch-agent=torch_agent.torch_agent:main
|
||||
|
||||
[options.packages.find]
|
||||
exclude=test
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
import setuptools
|
||||
|
||||
setuptools.setup()
|
|
@ -1,98 +0,0 @@
|
|||
from stem.control import Controller
|
||||
import stem.connection
|
||||
import paho.mqtt.client as mqtt
|
||||
import ssl
|
||||
import socks
|
||||
import socket
|
||||
import json
|
||||
import configparser
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from os import environ
|
||||
|
||||
parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT')
|
||||
|
||||
parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch',
|
||||
help='configuration directory (default: /etc/torch)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
configPath = args.configPath
|
||||
|
||||
if "TORCH_CONFIG_DIR" in environ:
|
||||
configPath = environ.get("TORCH_CONFIG_DIR")
|
||||
|
||||
if not configPath.endswith("/"):
|
||||
configPath = configPath + "/"
|
||||
|
||||
print("Using torch configuration path: " + configPath)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(configPath + "torch.conf")
|
||||
|
||||
torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050)
|
||||
torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051)
|
||||
|
||||
sshPort = config['ssh'].getint('Port', fallback = 22)
|
||||
|
||||
mqttConfig = config['mqtt']
|
||||
mqttBrokerHost = mqttConfig.get('BrokerHost', fallback = "localhost")
|
||||
mqttBrokerPort = mqttConfig.getint('BrokerPort', fallback = 1883)
|
||||
clientID = mqttConfig.get('ClientID', fallback = socket.gethostname())
|
||||
mqttTopic = mqttConfig.get('Topic', fallback = "torch/%s/onion_url" % (clientID))
|
||||
|
||||
mqttRequireCertificate = mqttConfig.getboolean(
|
||||
'RequireCertificate',
|
||||
fallback = False)
|
||||
|
||||
mqttCaFile = configPath + mqttConfig.get('CaFile')
|
||||
mqttCertFile = configPath + mqttConfig.get('CertFile')
|
||||
mqttKeyFile = configPath + mqttConfig.get('KeyFile')
|
||||
|
||||
with Controller.from_port(port = torControllerPort) as controller:
|
||||
|
||||
protocolInfo = stem.connection.get_protocolinfo(controller)
|
||||
|
||||
stem.connection.authenticate_safecookie(
|
||||
controller,
|
||||
protocolInfo.cookie_path)
|
||||
|
||||
print("Connected to Tor on port %s" % (torControllerPort))
|
||||
|
||||
service = controller.create_ephemeral_hidden_service(
|
||||
sshPort,
|
||||
detached = True)
|
||||
|
||||
onionAddress = "%s.onion" % (service.service_id)
|
||||
|
||||
print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress))
|
||||
|
||||
payload = {
|
||||
'clientId': clientID,
|
||||
'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),
|
||||
'onionAddress': onionAddress,
|
||||
'sshPort': sshPort
|
||||
}
|
||||
|
||||
client = mqtt.Client()
|
||||
protocol = "mqtt"
|
||||
|
||||
if mqttRequireCertificate:
|
||||
client.tls_set(
|
||||
ca_certs = mqttCaFile,
|
||||
certfile = mqttCertFile,
|
||||
keyfile = mqttKeyFile,
|
||||
cert_reqs=ssl.CERT_REQUIRED)
|
||||
protocol = "mqtts"
|
||||
|
||||
if mqttBrokerHost.endswith(".onion"):
|
||||
client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort)
|
||||
client.tls_insecure_set(True)
|
||||
|
||||
client.connect(mqttBrokerHost, mqttBrokerPort, 60)
|
||||
client.publish(mqttTopic, json.dumps(payload))
|
||||
print("Connected to MQTT Broker at %s://%s:%s/%s" % (protocol, mqttBrokerHost, mqttBrokerPort, mqttTopic))
|
||||
print("Published payload: " + json.dumps(payload))
|
||||
|
||||
client.disconnect()
|
||||
print("Disconnected from MQTT Broker")
|
37
torch.conf
37
torch.conf
|
@ -1,19 +1,48 @@
|
|||
#################
|
||||
# The `tor` section heading is required
|
||||
[tor]
|
||||
|
||||
# Optional: The Tor onion proxy host and port (default: 127.0.0.1:9050)
|
||||
#ProxyHost 127.0.0.1
|
||||
ProxyPort = 9050
|
||||
|
||||
# Optional: The Tor controller port (default: 9051) for creating new hidden services
|
||||
ControllerPort = 9051
|
||||
|
||||
|
||||
#################
|
||||
# The `ssh` section heading is required
|
||||
[ssh]
|
||||
|
||||
# Optional: Local SSH sevice port (default: 22)
|
||||
Port = 22
|
||||
|
||||
|
||||
#################
|
||||
# The `mqtt` section heading is required
|
||||
[mqtt]
|
||||
BrokerHost = mqtt.example.com # OR example1i3uyrbfoi3fi.onion
|
||||
|
||||
# Optional: The MQTT broker host and port (default: localhost:1883)
|
||||
# Can be either IPv4 or Tor onion hostname
|
||||
BrokerHost = mqtt.example.com
|
||||
#BrokerHost = example1i3uyrbfoi3fi.onion
|
||||
BrokerPort = 1883
|
||||
|
||||
# Optional: ID that will be used as an MQTT client ID when connecting to the broker (defaults to the current host's hostname)
|
||||
ClientID = my-client
|
||||
Topic = example/topic
|
||||
|
||||
### Options for Using TLS
|
||||
# Optional: Topic to be used when publishing connection info (defaults to 'torch/[hostname]/onion_url')
|
||||
#Topic = example/topic
|
||||
|
||||
### Optional: TLS Options
|
||||
#
|
||||
# Note: when CaFile, CertFile and KeyFile are ALL defined, then TLS (MQTTS) is used to connect to the broker. Otherwise MQTT is used.
|
||||
#
|
||||
|
||||
# Optional: Whether or not TORch Agent will verify the hostname of the broker and require it to match the name on the certificate the broker provides. This will be automatically DISABLED for connections to Tor onion hosts
|
||||
#RequireCertificate = true
|
||||
|
||||
#CaFile = ca.crt
|
||||
#CertFile = client.crt
|
||||
#KeyFile = client.key
|
||||
#KeyFile = client.key
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.0.6"
|
|
@ -0,0 +1,5 @@
|
|||
import sys
|
||||
from torch_agent import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -0,0 +1,127 @@
|
|||
import argparse
|
||||
import configparser
|
||||
import json
|
||||
import socket
|
||||
import ssl
|
||||
from datetime import datetime
|
||||
from os import environ
|
||||
|
||||
import paho.mqtt.publish as publish
|
||||
import socks
|
||||
import stem.connection
|
||||
from stem.control import Controller
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT')
|
||||
|
||||
parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch',
|
||||
help='configuration directory (default: /etc/torch)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
config_path = args.configPath
|
||||
|
||||
if "TORCH_CONFIG_DIR" in environ:
|
||||
config_path = environ.get("TORCH_CONFIG_DIR")
|
||||
|
||||
if not config_path.endswith("/"):
|
||||
config_path = config_path + "/"
|
||||
|
||||
print("Using torch configuration path: " + config_path)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
configuration_file_path = config_path + "torch.conf"
|
||||
print("Reading configuration file at '%s'" % configuration_file_path)
|
||||
config.read(configuration_file_path)
|
||||
|
||||
tor_proxy_host = config['tor'].get('ProxyHost', fallback="127.0.0.1")
|
||||
tor_proxy_port = config['tor'].getint('ProxyPort', fallback=9050)
|
||||
tor_controller_port = config['tor'].getint('ControllerPort', fallback=9051)
|
||||
|
||||
ssh_port = config['ssh'].getint('Port', fallback=22)
|
||||
|
||||
mqtt_config = config['mqtt']
|
||||
mqtt_broker_host = mqtt_config.get('BrokerHost', fallback="localhost")
|
||||
mqtt_broker_port = mqtt_config.getint('BrokerPort', fallback=1883)
|
||||
mqtt_broker_using_tor = mqtt_broker_host.endswith(".onion")
|
||||
mqtt_client_id = mqtt_config.get('ClientID', fallback=socket.gethostname())
|
||||
mqtt_topic = mqtt_config.get('Topic', fallback="torch/%s/onion_url" % mqtt_client_id)
|
||||
|
||||
mqtt_require_certificate = mqtt_config.getboolean(
|
||||
'RequireCertificate',
|
||||
fallback=False)
|
||||
|
||||
mqtt_ca_file = mqtt_config.get('CaFile', fallback=None)
|
||||
mqtt_ca_file = config_path + mqtt_ca_file
|
||||
mqtt_cert_file = mqtt_config.get('CertFile', fallback=None)
|
||||
mqtt_cert_file = config_path + mqtt_cert_file
|
||||
mqtt_key_file = mqtt_config.get('KeyFile', fallback=None)
|
||||
mqtt_key_file = config_path + mqtt_key_file
|
||||
|
||||
mqtt_use_tls = \
|
||||
mqtt_ca_file is not None and \
|
||||
mqtt_cert_file is not None and \
|
||||
mqtt_key_file is not None
|
||||
|
||||
print("Connecting to local TOR controller on port %s" % tor_controller_port)
|
||||
|
||||
with Controller.from_port(port=tor_controller_port) as controller:
|
||||
|
||||
protocol_info = stem.connection.get_protocolinfo(controller)
|
||||
|
||||
stem.connection.authenticate_safecookie(controller, protocol_info.cookie_path)
|
||||
|
||||
print("Creating TOR Hidden Service...")
|
||||
|
||||
service = controller.create_ephemeral_hidden_service(ssh_port, detached=True)
|
||||
|
||||
onion_address = "%s.onion" % service.service_id
|
||||
|
||||
print("Created Tor Hidden Service for local service on port %s at %s" % (ssh_port, onion_address))
|
||||
|
||||
protocol = "mqtt"
|
||||
tls_args = None
|
||||
proxy_args = None
|
||||
|
||||
cert_required = ssl.CERT_OPTIONAL
|
||||
if mqtt_require_certificate:
|
||||
cert_required = ssl.CERT_REQUIRED
|
||||
|
||||
if mqtt_broker_using_tor:
|
||||
cert_required = ssl.CERT_OPTIONAL
|
||||
proxy_args = {
|
||||
'proxy_type': socks.SOCKS5,
|
||||
'proxy_addr': tor_proxy_host,
|
||||
'proxy_port': tor_proxy_port
|
||||
}
|
||||
|
||||
if mqtt_use_tls:
|
||||
protocol = "mqtts"
|
||||
tls_args = {
|
||||
'ca_certs': mqtt_ca_file,
|
||||
'certfile': mqtt_cert_file,
|
||||
'keyfile': mqtt_key_file,
|
||||
'cert_reqs': cert_required
|
||||
}
|
||||
|
||||
print("Publishing to MQTT broker: %s://%s:%s/%s" % (protocol, mqtt_broker_host, mqtt_broker_port, mqtt_topic))
|
||||
if mqtt_broker_using_tor:
|
||||
print("--> Using TOR proxy: %s:%s" % (tor_proxy_host, tor_proxy_port))
|
||||
|
||||
payload = json.dumps({
|
||||
'clientId': mqtt_client_id,
|
||||
'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),
|
||||
'onionAddress': onion_address,
|
||||
'sshPort': ssh_port
|
||||
})
|
||||
|
||||
publish.single(mqtt_topic,
|
||||
payload,
|
||||
qos=1,
|
||||
hostname=mqtt_broker_host,
|
||||
port=mqtt_broker_port,
|
||||
client_id=mqtt_client_id,
|
||||
tls=tls_args,
|
||||
proxy_args=proxy_args)
|
Loading…
Reference in New Issue