├── .gitignore
├── .gitmodules
├── .travis.yml
├── README.md
├── docs
├── join.md
├── local-server-howto.md
└── server-internals.md
├── etc
├── cross-domain-policy.xml
├── init.properties
└── tigase.conf
├── pom.xml
├── scripts
├── installer.sh
├── repo.sh
└── tigase.sh
└── vagrant
├── .gitignore
├── Vagrantfile
├── bootstrap.sh
├── conf
├── fail2ban
│ └── jail.local
└── init.properties.dist
├── data
├── bash_aliases
└── custom.sh
├── export.sh
├── install.sh
├── local.properties.dist
├── setup
├── cleanup.sh
├── functions.sh
├── java8.sh
├── kontalk-config.sh
├── kontalk-database.sh
├── kontalk-keys.sh
├── mysql.sh
├── ssh.sh
├── system.sh
└── tigase-kontalk.sh
└── tools
└── editconf.py
/.gitignore:
--------------------------------------------------------------------------------
1 | /jars
2 | /logs
3 | /certs
4 | /etc/config-dump.properties
5 | *.pem
6 | *.iml
7 | .vagrant
8 | *.kch
9 | /scripts/admin
10 | /.idea
11 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "tigase-server"]
2 | path = tigase-server
3 | url = https://github.com/kontalk/tigase-server.git
4 | [submodule "tigase-extension"]
5 | path = tigase-extension
6 | url = https://github.com/kontalk/tigase-extension.git
7 | [submodule "tigase-pubsub"]
8 | path = tigase-pubsub
9 | url = https://github.com/kontalk/tigase-pubsub.git
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | dist: trusty
3 | language: java
4 | jdk:
5 | - openjdk8
6 |
7 | before_install:
8 | - sudo apt-get update -qq
9 | - sudo apt-get install -qq libkyotocabinet16 libkyotocabinet-dev
10 | - wget http://fallabs.com/kyotocabinet/javapkg/kyotocabinet-java-1.24.tar.gz
11 | - tar -xzf kyotocabinet-java-1.24.tar.gz
12 | - cd kyotocabinet-java-1.24 && ./configure --prefix=/usr && make && sudo make install && cd ..
13 |
14 | install:
15 | - mkdir -p jars && ln -s /usr/lib/libjkyotocabinet.so jars/libjkyotocabinet.so
16 |
17 | jobs:
18 | include:
19 | - stage: build docker image
20 | script:
21 | - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
22 | - git clone https://github.com/kontalk/xmppserver-docker.git xmppserver-docker
23 | - docker build --build-arg BRANCH=${TRAVIS_COMMIT} -t kontalk/xmppserver:$(echo ${TRAVIS_COMMIT} | colrm 8) xmppserver-docker/tigase
24 | - docker images
25 | - docker push kontalk/xmppserver:$(echo ${TRAVIS_COMMIT} | colrm 8)
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Kontalk Tigase server
2 | =====================
3 |
4 | ### Setting up a Kontalk server
5 |
6 | A Kontalk server can be quickly installed and set up in a few minutes if you use
7 | [our Docker environment](//github.com/kontalk/xmppserver-docker).
8 |
9 | **You can get [support in our forum](https://forum.kontalk.org/) only if you use our Docker environment.**
10 | We don't support other means of installations because setting up a Kontalk server is complicated and
11 | we put severe efforts to make it easier. You can however provide feedback on our Docker installation
12 | by opening a topic in the forum or by [opening an issue](//github.com/kontalk/xmppserver-docker/issues/new).
13 |
14 | ### Build
15 |
16 | This repository contains build and startup scripts for setting up and running
17 | a Kontalk server.
18 |
19 | To build the Kontalk server, run this command in your terminal:
20 |
21 | ```
22 | wget -qq -O - https://raw.githubusercontent.com/kontalk/tigase-kontalk/master/scripts/installer.sh | bash
23 | ```
24 |
25 | The script will clone this repository in a new folder called "kontalk-server" and build everything.
26 |
27 | After building, configure the server through `etc/tigase.conf` and `etc/init.properties` and after that
28 | you should get it up and running:
29 |
30 | ```
31 | scripts/tigase.sh start etc/tigase.conf
32 | ```
33 |
34 | We also wrote a [basic tutorial](docs/local-server-howto.md) that goes more in depth with the setup of a Kontalk server.
35 | The default `etc/init.properties` contains a few explanation comments.
36 |
--------------------------------------------------------------------------------
/docs/join.md:
--------------------------------------------------------------------------------
1 | # Join a Kontalk network
2 |
3 | In order to join a network, you need to configure some other parameters to some predefined values.
4 |
5 | ## Registration
6 |
7 | If you use Nexmo verify API for registration (NexmoVerifyProvider) you must set the `brand` parameter to the network brand name. For example, the kontalk.net network requires this value to be "Kontalk":
8 |
9 | ```
10 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/brand=Kontalk
11 | ```
12 |
13 | ## Server list
14 |
15 | Every server needs to know the current list of all servers in the network and which of them are active or not. You can request a list of all the servers to any of the other servers' administrators. Some automatic method will be implemented in the future.
16 |
17 | ## Requesting a link
18 |
19 | Although Kontalk works in the XMPP federated network, requesting a link can have some advantages and will form an agreement that will simplify some collaboration tasks between the servers. Please refer to the [kontalk.net join page](//github.com/kontalk/network/wiki/Join).
20 |
--------------------------------------------------------------------------------
/docs/local-server-howto.md:
--------------------------------------------------------------------------------
1 | > This is a low-level tutorial for people developing on the Kontalk server. Please refer to documents in
2 | > [our Docker repository](//github.com/kontalk/xmppserver-docker) if you want to setup a server instance
3 | > for production use.
4 |
5 | **WARNING** this tutorial is NOT for newbies. Linux system administrator skills are required. Also, it takes for granted concepts like GPG keys and SSL certificates, which are assumed to be known by the reader.
6 |
7 | ## Introduction ##
8 |
9 | This tutorial will help you setup a working instance of a Kontalk XMPP server on Linux system. You can use it for your own purposes or you can link to the kontalk.net network (please refer to the [[Join]] page for that).
10 |
11 | ## Dependencies ##
12 |
13 | Our preferred system is Debian, but any GNU/Linux distribution should work.
14 |
15 | * MySQL server >= 5.5
16 | * GnuPG >= 2.1.5
17 | * GPGPME >= 1.4
18 | * JDK >= 1.8
19 | * Kyoto Cabinet >= 1.2.76
20 | * Kyoto Cabinet for Java >= 1.24
21 |
22 | For compiling you will need also:
23 |
24 | * make
25 | * Maven 3
26 | * gcc/g++
27 | * git
28 | * development packages for Kyoto Cabinet and GPGME
29 |
30 | ## Download sources ##
31 |
32 | After installing all the requirements, you can download the source code. We'll use the production branch, which is supposed to be stable.
33 |
34 | Next step is Kontalk server source code.
35 |
36 | ```shell
37 | git clone -b production https://github.com/kontalk/tigase-server.git
38 | git clone -b production https://github.com/kontalk/tigase-extension.git
39 | git clone https://github.com/kontalk/tigase-kontalk.git
40 | cd tigase-kontalk
41 | mvn install
42 | ln -sf /usr/lib/libjkyotocabinet.so jars/libjkyotocabinet.so
43 | ```
44 |
45 | **NOTE**: the last command will change depending on where you installed Kyoto Cabinet for Java.
46 |
47 | ## Create database ##
48 |
49 | Database objects for Tigase itself and Kontalk must be created now. Run these commands while standing in same directory of the previous commands:
50 |
51 | ```shell
52 | cd tigase-server
53 | rm -f jars/*.jar
54 | cp ../tigase-kontalk/jars/*.jar jars/
55 | java -cp "jars/*" tigase.util.DBSchemaLoader -dbHostname db -dbType mysql -schemaVersion 7-1 \
56 | -dbName ${MYSQL_DATABASE} -dbUser ${MYSQL_USER} -dbPass ${MYSQL_PASSWORD} \
57 | -logLevel ALL -useSSL false
58 | java -cp "jars/*" tigase.util.DBSchemaLoader -dbHostname db -dbType mysql -schemaVersion 7-1 \
59 | -dbName ${MYSQL_DATABASE} -dbUser ${MYSQL_USER} -dbPass ${MYSQL_PASSWORD} \
60 | -logLevel ALL -useSSL false \
61 | database/mysql-pubsub-schema-3.0.0.sql
62 | ```
63 |
64 | Replace the variables above with the proper MySQL information.
65 |
66 | Now it's time for Kontalk database objects. Run the following scripts in the same database using any MySQL client:
67 |
68 | * `tigase-extension/data/network.sql` which will create a *servers* table that you will need to fill later
69 | * `tigase-extension/data/messages.sql` creates the *messages* table for offline message delivery
70 | * `tigase-extension/data/registration.sql` if you plan to support registration (and I bet you do)
71 | * `tigase-extension/data/push.sql` if you want to support push notifications
72 |
73 | ## Create GPG key ##
74 |
75 | Create a GPG key for both signing and encrypting, and remove its passphrase after creating it. Take note of the key fingerprint, you will need it.
76 | I strongly suggest to create a local keychain instead of using the one in your home directory. However, if you created a user just for Kontalk, you might want to use the user's default keychain in `~/.gnupg`.
77 |
78 | If you use a custom GPG home directory, you can set it in a variable in `tigase-kontalk/etc/tigase.conf`.
79 |
80 | Export both your new private and public keys separately, using the following commands:
81 |
82 | ```shell
83 | gpg2 --export [fingerprint] >tigase-kontalk/server-public.key
84 | gpg2 --export-secret-key [fingerprint] >tigase-kontalk/server-private.key
85 | ```
86 |
87 | The filenames are important because they are referenced by the configuration files.
88 |
89 | Now log into your new database and insert a row in the *servers* database with the fingerprint of the key you've just created (without spaces) and the XMPP service host name of your server, with the enabled field set to 1:
90 |
91 | ```sql
92 | INSERT INTO servers (fingerprint, host, enabled) VALUES('[fingerprint]', '[service_name]', 1);
93 | ```
94 |
95 | ## Create SSL certificate ##
96 |
97 | Create a SSL certificate which will be used for STARTTLS. You can generate a self-signed certificate or request one from a CA. Save the private key and certificate chain in PEM format and concatenate them:
98 |
99 | ```shell
100 | cat certificate.pem privatekey.pem >tigase-kontalk/certs/hostname.pem
101 | ```
102 |
103 | The name of the file must match the host name you will use as the XMPP host for your server.
104 |
105 | ## Configuration ##
106 |
107 | A default configuration file can be found in `etc/init.properties`. For general Tigase configuration, you can refer to its documentation.
108 | All Kontalk specific parameters have comments explaining how to set them.
109 |
110 | ## Registration ##
111 |
112 | Registration is already enabled in default configuration, using the `adb` tool to send SMS messages to an Android emulator. If you want real SMS verification, you need to choose a provider. It can be configured in `sess-man/plugins-conf/kontalk\:jabber\:iq\:register/provider`. Available providers are:
113 |
114 | * `NexmoSMSProvider` - uses [Nexmo](https://nexmo.com/) to manually send SMS messages and use the local database for storing verification PINs
115 | * `NexmoVerifyProvider` uses [Nexmo](https://nexmo.com/) verification API which can handle the whole verification workflow
116 | * `AndroidEmulatorProvider` - uses adb to send SMS messages to an Android emulator
117 | * `DummyProvider` - always accepts a verification code equal to the sender number configured
118 |
119 | Those names must be prefixed in configuration with the full package name `org.kontalk.xmppserver.registration.`.
120 |
121 | For providers backed by Nexmo, you need to configure two other additional parameters, namely `username` and `password` with Nexmo API key and API secret respectively.
122 | For Nexmo verification API provider, one more parameter called `brand` should have value "Kontalk" (it will appear in the verification SMS text):
123 |
124 | This is an example configuration using the Nexmo verification API:
125 |
126 | ```
127 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/providers[s]=nexmo=org.kontalk.xmppserver.registration.NexmoVerifyProvider
128 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/nexmo-sender=SENDERID
129 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/nexmo-username=APIKEY
130 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/nexmo-password=APISECRET
131 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/nexmo-brand=YOURBRAND
132 | ```
133 |
134 | The `providers[s]` property lists which providers should be loaded. It should be in this form:
135 |
136 | ```
137 | provider_name=provider_class,provider_name=provider_class,...
138 | ```
139 |
140 | The provider name can be anything, as long as it's the same among all its parameters, defined right after:
141 |
142 | ```
143 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/provider_name-param_name=param_value
144 | ```
145 |
146 | When configuring multiple providers, you can set a default provider and a fallback
147 | one to be used when the default one fails for whatever reason:
148 |
149 | ```
150 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/default-provider=nexmo
151 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/fallback-provider=dummy
152 | ```
153 |
154 | If no default or fallback providers are configured, choice will be driven by the order
155 | you configured them in the `providers[s]` property.
156 |
157 |
158 | For remote test servers, the dummy provider is a good way to test registrations:
159 |
160 | ```
161 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/providers[s]=dummy=org.kontalk.xmppserver.registration.DummyProvider
162 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/dummy-sender=123456
163 | ```
164 |
165 | This will configure your server to always accept 123456 as a valid verification code for any account registered.
166 |
167 |
168 | To disable registration (which makes your server pretty much useless), remove:
169 |
170 | ```
171 | +kontalk:jabber:iq:register
172 | ```
173 |
174 | from the `--sm-plugins` directive and remove all lines beginning with `sess-man/plugins-conf/kontalk\:jabber\:iq\:register`.
175 |
176 | ## Push notifications ##
177 |
178 | First of all, enable push support in the server by adding:
179 |
180 | ```
181 | +kontalk:push:legacy
182 | ```
183 |
184 | to `--sm-plugins`.
185 |
186 | Then uncomment the `KontalkLegacyPushComponent` component part and configure it with your GCM parameters.
187 |
188 | ## File upload support ##
189 |
190 | > TODO configure HttpFileUploadComponent
191 |
192 | ## Running ##
193 |
194 | Place your shell in the `tigase-kontalk` directory and run:
195 |
196 | ```shell
197 | scripts/tigase.sh start etc/tigase.conf
198 | ```
199 |
200 | Tigase will fork in the background and start logging in the `logs` directory.
201 |
--------------------------------------------------------------------------------
/docs/server-internals.md:
--------------------------------------------------------------------------------
1 | > This document is a work in progress.
2 |
3 | Server internals
4 | ================
5 | This article describes some internals of the Kontalk server, how it was
6 | developed and what customizations were needed to make it work.
7 |
8 |
9 | ## Software environment
10 | Kontalk is based on a patched version of the
11 | [Tigase XMPP server](https://projects.tigase.org), usually on top of the
12 | release branch. We patched a few things mainly to add more reliability and
13 | pieces of code to better integrate with our extensions (more about those later
14 | on).
15 | In addition to that, we developed a few extensions on top of the plugins and
16 | component APIs provided by Tigase which proved to be very useful and well
17 | organized. Extensions were developed only when Tigase didn't provide its own
18 | plugin or when the Tigase implementation wasn't enough for our needs.
19 |
20 |
21 | ## Patches to Tigase
22 | We always [rebase on top of the upstream release branch](https://github.com/kontalk/tigase-server/commits/master)
23 | so our commits will always be at the top of history. Here is a quick list of
24 | what we did.
25 |
26 | ### Patch: allow self-signed certificates in client certificate authentication
27 | Kontalk authentication is client-certificate based, but signature check is done
28 | on the PGP key, not on the X.509 certificate (although a X.509 certificate is
29 | used to encapsulate, more on that later on). Therefore, those "bridge
30 | certificates" as we call them are simply self-signed. Tigase doesn't allow
31 | client certificate authentication with self-signed certificates, so we had to
32 | patch it.
33 |
34 | ### Patch: subscription pre-approval
35 | XMPP defines something called [subscription pre-approvals](http://xmpp.org/rfcs/rfc6121.html#sub-preapproval)
36 | which is used to approve (hence the name) a subscription request by somebody
37 | preemptively, so that when that somebody requests a subscription to that user,
38 | it will get automatically approved by the server without requiring any other
39 | action. A merge request is currently pending to the Tigase project with the code
40 | we donated.
41 |
42 | ### Patch: minor reliability checks
43 | There are some minor issues with Tigase regarding aggressive delivery. Tigase
44 | does guarantee message delivery when using Session Management, however there are
45 | a couple of borderline cases where some messages might get lost. It happens only
46 | in severely broken connections, however for mobile phones this is not so rare.
47 |
48 |
49 | ## Kontalk extensions
50 | On top of the described patches, a separate set of plugins and components were
51 | delivered to fully support the Kontalk workflow.
52 |
53 | ### PGP-key based authentication
54 | This is the central authentication module that allows authentication through
55 | means of a PGP key previously signed by the server during registration.
56 | Despite an OpenPGP-based TLS RFC exists, the only known implementation to
57 | mankind is GnuTLS. And being everything in Java not based on GnuTLS, we had to
58 | make something up to make this work. So clients build a X.509 certificate that
59 | encapsulates the PGP key. During registration, servers sign that embedded PGP
60 | key and return it to the client. The signed key is then embedded again in the
61 | wrapper certificate to log in. To certify that the certificate was indeed
62 | created by the same entity that owns the embedded PGP key, the private key
63 | of the PGP key is the same private key of the wrapper certificate.
64 |
65 | We generated a random UUID/OID for the X.509 extension used to encapsulate the
66 | PGP key:
67 |
68 | ```
69 | UUID: 24e844a0-6cbc-11e3-8997-0002a5d5c51b
70 | OID: 2.25.49058212633447845622587297037800555803
71 | ```
72 |
73 | ### Registration
74 | Because of how Kontalk was designed, we needed some extensions to support
75 | phone number-based registration. Our extension is built on top of
76 | [XEP-0077: In-band registration](http://xmpp.org/extensions/xep-0077.html) with
77 | a few more form fields to include some stuff such as verification code, phone
78 | number and public key. More details on the XMPP extension can be found in the
79 | [relevant spec document](https://github.com/kontalk/specs/blob/master/register.md).
80 |
81 | We built something pretty much modular that can be extended to support more
82 | telephony providers. We currently support:
83 |
84 | * Nexmo (SMS and verify APIs)
85 | * Cognalys
86 | * Checkmobi (CLI and missed-call)
87 | * JMP.Chat
88 | * Android emulator (used in local tests)
89 |
90 | ### Roster match
91 | We did this with a component. The component is responsible for communicating
92 | both with clients and with other servers in the network. It's used to find other
93 | registered users in the network given their phone numbers.
94 | More details on the XMPP extension in the [relevant spec document](https://github.com/kontalk/specs/blob/master/roster-match.md).
95 |
96 | ### Public key publish
97 | TODO
98 |
99 | ### Server list command
100 | TODO
101 |
102 | ### Extended addressing
103 | TODO
104 |
105 | ### Media upload
106 | TODO
107 |
108 | ### Push notifications support
109 | TODO
110 |
111 |
--------------------------------------------------------------------------------
/etc/cross-domain-policy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/etc/init.properties:
--------------------------------------------------------------------------------
1 | # Default Kontalk configuration, fine for most configurations
2 |
3 | # XMPP host where you're serving your Kontalk instance
4 | # Kontalk extensions support one virtual host only for now
5 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/host=prime.kontalk.net
6 | # Virtual hosts served by this instance (must match the above)
7 | --virt-hosts=prime.kontalk.net
8 | # Administrator JID (must be in the above domain)
9 | --admins=admin@prime.kontalk.net
10 |
11 | # Fingerprint of the GPG server key
12 | sess-man/plugins-conf/fingerprint=37D0E678CDD19FB9B182B3804C9539B401F8229C
13 |
14 | # The global network domain (do not change this if you want to participate in the Kontalk global network)
15 | sess-man/plugins-conf/network-domain=kontalk.net
16 | sess-man/plugins-conf/service-terms-url=https://kontalk.github.io/network/privacy
17 |
18 | # Database configuration (all three db-uri parameters must be identical)
19 | --user-db=mysql
20 | --user-db-uri=jdbc:mysql://localhost:3306/kontalk?user=kontalk&password=kontalk&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
21 | sess-man/plugins-conf/db-uri=jdbc:mysql://localhost:3306/kontalk?user=kontalk&password=kontalk&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
22 | pubsub/pubsub-repo-url=jdbc:mysql://localhost:3306/kontalk?user=kontalk&password=kontalk&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
23 |
24 | # Registration provider configuration
25 | # Dummy provider configuration
26 | # It will always accept 123456 as a valid verification code
27 | # Good for a remote test server
28 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/providers[s]=dummy=org.kontalk.xmppserver.registration.DummyProvider
29 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/dummy-sender=123456
30 | # set to true to disable registration security checks
31 | # deprecated - sess-man/plugins-conf/kontalk\:jabber\:iq\:register/disable-security[B]=true
32 |
33 | # security features to enable - leave empty to disable all
34 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/security[s]=throttling-ip,throttling-phone,throttling-prefix
35 |
36 | # IP-based throttling: delay in seconds
37 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-ip.delay[I]=30
38 | # IP-based throttling: max attempts before triggering throttling
39 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-ip.trigger-attempts[I]=3
40 |
41 | # phone-based throttling: delay in seconds
42 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-phone.delay[I]=30
43 | # phone-based throttling: max attempts before triggering throttling
44 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-phone.trigger-attempts[I]=3
45 |
46 | # prefix-based throttling: delay in seconds
47 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-prefix.delay[I]=30
48 | # prefix-based throttling: max attempts before triggering throttling
49 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-prefix.trigger-attempts[I]=3
50 | # prefix-based throttling: most significant digits to consider (excluding the plus sign)
51 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-prefix.length[I]=6
52 |
53 | # Dummy provider configuration
54 | # It will always accept 123456 as a valid verification code
55 | # Good for a remote test server
56 | #sess-man/plugins-conf/kontalk\:jabber\:iq\:register/providers[s]=dummy=org.kontalk.xmppserver.registration.DummyProvider
57 | #sess-man/plugins-conf/kontalk\:jabber\:iq\:register/dummy-sender=123456
58 |
59 | # Endpoints configuration
60 | # All endpoints must declare a clientCertCA pointing to a valid certificate chain file
61 | # (any CA chain will do, it won't actually be used but Tigase won't work without it)
62 |
63 | # Client endpoint configuration
64 | --c2s-ports=5999,5222,5223,8443
65 | c2s/connections/5223/socket=ssl
66 | c2s/connections/8443/socket=ssl
67 | c2s/clientCertCA=trusted.pem
68 |
69 | # Websocket endpoint configuration
70 | message-router/components/msg-receivers/ws2s.active[B]=false
71 | ws2s/connections/5290/socket=ssl
72 | ws2s/clientCertCA=trusted.pem
73 |
74 | # BOSH endpoint configuration
75 | message-router/components/msg-receivers/bosh.active[B]=false
76 | bosh/connections/5280/socket=ssl
77 | bosh/clientCertCA=trusted.pem
78 |
79 | # S2S endpoint configuration (comment to disable XMPP federation)
80 | --s2s-ports=5269
81 |
82 | # Enabled plugins, comma-separated
83 | # prefixed with a minus (-) means not loaded, prefixed with nothing or with a plus (+) means loaded.
84 | # add "+kontalk:push:legacy" to enable Kontalk push notifications (external component must also be configured below)
85 | --sm-plugins=-amp,-message-carbons,-jabber:iq:auth,-jabber:iq:register,-jabber:iq:privacy,-jabber:iq:last,-msgoffline,-urn:xmpp:blocking,-urn:xmpp:csi:0,+message,+msgoffline2,+presence:urn:xmpp:pubkey:2,+kontalk:jabber:iq:register,+kontalk:jabber:iq:roster,+urn:xmpp:pubkey:2,+kontalk:urn:xmpp:blocking,+kontalk:urn:xmpp:csi:0,+kontalk:jabber:iq:last,+pep
86 |
87 | # Comment these to revert to default logging
88 | --debug=server,xmpp.impl
89 | --debug-packages=org.kontalk
90 |
91 | # External components. Do not change the default names!
92 | # --comp-xxx parameter pairs follow a numbering order
93 | # whenever you delete/comment or insert a component, remember to fix the numbering!!
94 |
95 | # Network component
96 | # enables server list commands. Particularly needed if participating in a global network
97 | --comp-name-1=network
98 | --comp-class-1=org.kontalk.xmppserver.NetworkComponent
99 |
100 | # Phone number lookup component
101 | # enables discovery of contacts in the local/global network by their phone numbers
102 | --comp-name-2=probe
103 | --comp-class-2=org.kontalk.xmppserver.probe.ProbeComponent
104 |
105 | # External XMPP component protocol
106 | # needed for HttpFileUploadComponent
107 | --comp-name-3=ext
108 | --comp-class-3=tigase.server.ext.ComponentProtocol
109 | # these must match HttpFileUploadComponent configuration
110 | --external=media.prime.kontalk.net:secret:listen:5270
111 |
112 | # For group chats
113 | --comp-name-4=multicast
114 | --comp-class-4=org.kontalk.xmppserver.ExtendedAddressing
115 |
116 | # For other stuff, including OMEMO
117 | --comp-name-5=pubsub
118 | --comp-class-5=tigase.pubsub.PubSubComponent
119 |
120 | # GCM push notifications
121 | # remember to fix --sm-plugins too (see above)
122 | #--comp-name-6=push
123 | #--comp-class-6=org.kontalk.xmppserver.KontalkLegacyPushComponent
124 | #push/provider=org.kontalk.xmppserver.push.GCMProvider
125 | #push/gcm-projectid=PROJECT-ID
126 | #push/gcm-apikey=API-KEY
127 |
128 | # Internal parameters
129 | # the following properties must not be changed unless you really know what you're doing
130 | basic-conf/auth-repo-params/sasl-mechs=EXTERNAL
131 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/factory=org.kontalk.xmppserver.auth.KontalkSaslServerFactory
132 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/mechanism-selector=org.kontalk.xmppserver.auth.KontalkMechanismSelector
133 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/callbackhandler-EXTERNAL=org.kontalk.xmppserver.auth.KontalkCertificateCallbackHandler
134 | sess-man/plugins-conf/presence-state/extended-presence-processors=org.kontalk.xmppserver.presence.PublicKeyPresence
135 | c2s/processors[s]=urn:xmpp:sm:3=org.kontalk.xmppserver.KontalkIOProcessor
136 | message-router/components/msg-receivers/amp.active[B]=false
137 | pubsub/pubsub-repo-class=tigase.pubsub.repository.PubSubDAOJDBC
138 | pubsub/persistent-pep[B]=true
139 | pubsub/send-last-published-item-on-presence[B]=true
140 | --vhost-anonymous-enabled=false
141 | --vhost-tls-required=false
142 | --hardened-mode=true
143 | config-type=--gen-config-def
144 |
--------------------------------------------------------------------------------
/etc/tigase.conf:
--------------------------------------------------------------------------------
1 | #osgiEnabled=(true|false)
2 | #osgiEnabled=false
3 | OSGI=${osgiEnabled}
4 | ENC="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
5 | DRV="-Djdbc.drivers=com.mysql.jdbc.Driver:org.postgresql.Driver:org.apache.derby.jdbc.EmbeddedDriver"
6 | #GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:ParallelCMSThreads=2 -XX:-ReduceInitialCardMarks"
7 | #EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA"
8 | #JMX_REMOTE_IP="-Djava.rmi.server.hostname=0.0.0.0"
9 | #JAVA_HOME="${JDKPath}"
10 | CLASSPATH=""
11 | JAVA_OPTIONS="${GC} ${EX} ${ENC} ${DRV} ${JMX_REMOTE_IP} -server -Xms100M -Xmx200M -XX:PermSize=32m -XX:MaxPermSize=256m -XX:MaxDirectMemorySize=128m -Djava.library.path=jars -Djdk.tls.ephemeralDHKeySize=2048 -Dpgp.secret.public=server-public.key -Dpgp.secret.private=server-private.key -Dpgp.keyring=keyring "
12 | TIGASE_CONFIG="etc/tigase.xml"
13 | TIGASE_OPTIONS=" --property-file etc/init.properties "
14 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 | org.kontalk
6 | tigase-kontalk
7 | Kontalk XMPP server
8 | devel
9 | pom
10 |
11 |
12 | tigase-server/modules/master
13 | tigase-pubsub
14 | tigase-extension
15 |
16 |
17 |
18 |
19 |
20 | org.apache.maven.plugins
21 | maven-dependency-plugin
22 | 3.0.0
23 |
24 |
25 | install
26 |
27 | copy-dependencies
28 |
29 |
30 | ${project.basedir}/jars
31 |
32 |
33 |
34 |
35 |
36 | maven-resources-plugin
37 | 3.0.2
38 |
39 |
40 | copy-resources
41 | install
42 |
43 | copy-resources
44 |
45 |
46 | jars
47 |
48 |
49 | tigase-extension/target/lib
50 |
51 | junit-*
52 | hamcrest-core-*
53 | slf4j-*
54 |
55 |
56 |
57 | tigase-server/target/lib
58 |
59 | junit-*
60 | hamcrest-core-*
61 | groovy-all-*
62 |
63 |
64 |
65 | tigase-pubsub/target/lib
66 |
67 | derby-*
68 | junit-*
69 | hamcrest-core-*
70 | groovy-all-*
71 |
72 |
73 |
74 | tigase-extension/target
75 |
76 | tigase-extension-*.jar
77 |
78 |
79 |
80 | tigase-pubsub/target
81 |
82 | tigase-pubsub-*.jar
83 |
84 |
85 |
86 |
87 |
88 |
89 | copy-scripts
90 | install
91 |
92 | copy-resources
93 |
94 |
95 | scripts/admin/sess-man
96 |
97 |
98 | tigase-extension/src/main/groovy/tigase/admin
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | mysql
111 | mysql-connector-java
112 | 5.1.43
113 |
114 |
115 | org.slf4j
116 | slf4j-log4j12
117 | 1.7.5
118 |
119 |
120 | biz.paluch.logging
121 | logstash-gelf
122 | 1.11.2
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/scripts/installer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Helper installation scripts for rapid download and building of the Kontalk server
3 | # It will install everything in the directory provided as a parameter (default: $PWD/kontalk-server)
4 | # A second parameter can be used to use a specific branch
5 | # To be used as a standalone script like this:
6 | # wget -qq -O - url_to_installer.sh | bash
7 |
8 | yell() { echo "$0: $*" >&2; }
9 | die() { yell "$*"; exit 1; }
10 | try() { "$@" || die "cannot $*"; }
11 | check_for() { which $@ >/dev/null || die "Unable to locate $*"; }
12 |
13 | check_programs()
14 | {
15 | # check for git
16 | check_for git
17 | # check for maven
18 | check_for mvn
19 | }
20 |
21 | # check for needed programs
22 | check_programs
23 |
24 | WORKDIR="$1"
25 | BRANCH="$2"
26 |
27 | if [ "$WORKDIR" == "" ]; then
28 | WORKDIR="$PWD/kontalk-server"
29 | fi
30 |
31 | if [ -a "$WORKDIR" ]; then
32 | die "Working directory $WORKDIR already exists."
33 | fi
34 |
35 | cd $(dirname "$WORKDIR")
36 |
37 | yell "Downloading sources"
38 |
39 | if [ "$BRANCH" == "" ]; then
40 | BRANCH="master"
41 | fi
42 |
43 | try git clone -n https://github.com/kontalk/tigase-kontalk.git ${WORKDIR} && (cd ${WORKDIR} && git checkout ${BRANCH} && git submodule update --init)
44 |
45 | cd kontalk-server
46 | mvn -DskipTests install
47 |
--------------------------------------------------------------------------------
/scripts/repo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | ##
3 | ## Tigase Jabber/XMPP Server
4 | ## Copyright (C) 2004-2012 "Artur Hefczyc"
5 | ##
6 | ## This program is free software: you can redistribute it and/or modify
7 | ## it under the terms of the GNU Affero General Public License as published by
8 | ## the Free Software Foundation, either version 3 of the License.
9 | ##
10 | ## This program is distributed in the hope that it will be useful,
11 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | ## GNU Affero General Public License for more details.
14 | ##
15 | ## You should have received a copy of the GNU Affero General Public License
16 | ## along with this program. Look for COPYING file in the top folder.
17 | ## If not, see http://www.gnu.org/licenses/.
18 | ##
19 | ## $Rev: $
20 | ## Last modified by $Author: $
21 | ## $Date: $
22 | ##
23 |
24 | D="-server -Xms100M -Xmx1500M -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Djdbc.drivers=com.mysql.jdbc.Driver:org.postgresql.Driver"
25 |
26 | MYSQL_REP="-sc tigase.db.jdbc.JDBCRepository -su jdbc:mysql://localhost/tigase?user=root&password=ciao"
27 |
28 | java $D -cp "jars/*" tigase.util.RepositoryUtils $MYSQL_REP $*
29 |
--------------------------------------------------------------------------------
/scripts/tigase.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | ##
3 | ## Tigase Jabber/XMPP Server
4 | ## Copyright (C) 2004-2012 "Artur Hefczyc"
5 | ##
6 | ## This program is free software: you can redistribute it and/or modify
7 | ## it under the terms of the GNU Affero General Public License as published by
8 | ## the Free Software Foundation, either version 3 of the License.
9 | ##
10 | ## This program is distributed in the hope that it will be useful,
11 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | ## GNU Affero General Public License for more details.
14 | ##
15 | ## You should have received a copy of the GNU Affero General Public License
16 | ## along with this program. Look for COPYING file in the top folder.
17 | ## If not, see http://www.gnu.org/licenses/.
18 | ##
19 | ## $Rev: $
20 | ## Last modified by $Author: $
21 | ## $Date: $
22 | ##
23 | #
24 | # This is Tigase (http://www.tigase.org) server startup file.
25 | #
26 | # First parameter is a command (start, stop and so on...),
27 | # second parameters is parameters file - the file where from
28 | # environment variables are read like:
29 | # JAVA_HOME
30 | # JAVA_OPTIONS
31 | # CLASSPATH
32 | # TIGASE_HOME
33 | # TIGASE_CONSOLE_LOG
34 | # TIGASE_PID
35 | # OSGI=true
36 | #
37 | # If not given the script will try to search for the file and if
38 | # not found default parameters will be used.
39 |
40 | function usage()
41 | {
42 | echo "Usage: $0 {start|stop|run|clear|clearrestart|restart|check|status} [params-file.conf]"
43 | exit 1
44 | }
45 |
46 | if [ -z "${2}" ] ; then
47 | DEF_PARAMS="tigase.conf"
48 | # Gentoo style config location
49 | if [ -f "/etc/conf.d/${DEF_PARAMS}" ] ; then
50 | TIGASE_PARAMS="/etc/conf.d/${DEF_PARAMS}"
51 | elif [ -f "/etc/${DEF_PARAMS}" ] ; then
52 | TIGASE_PARAMS="/etc/${DEF_PARAMS}"
53 | elif [ -f "/etc/tigase/${DEF_PARAMS}" ] ; then
54 | TIGASE_PARAMS="/etc/tigase/${DEF_PARAMS}"
55 | else
56 | TIGASE_PARAMS=""
57 | fi
58 | echo "No params-file.conf given. Using: '$TIGASE_PARAMS'"
59 | else
60 | TIGASE_PARAMS=${2}
61 | fi
62 |
63 | [[ -f "${TIGASE_PARAMS}" ]] && . ${TIGASE_PARAMS}
64 |
65 | if [ -z "${JAVA_HOME}" ] ; then
66 | echo "JAVA_HOME is not set."
67 | echo "Please set it to correct value before starting the sever."
68 | exit 1
69 | fi
70 |
71 | if [ -z "${TIGASE_HOME}" ] ; then
72 | if [ ${0:0:1} = '/' ] ; then
73 | TIGASE_HOME=${0}
74 | else
75 | TIGASE_HOME=${PWD}/${0}
76 | fi
77 | TIGASE_HOME=`dirname ${TIGASE_HOME}`
78 | TIGASE_HOME=`dirname ${TIGASE_HOME}`
79 |
80 | TIGASE_JAR=""
81 | fi
82 |
83 | if [ -n "${OSGI}" ] && ${OSGI} ; then
84 | LIB_DIR=jars
85 | JAR_FILE=${LIB_DIR}/org.apache.felix.main*.jar
86 | else
87 | LIB_DIR=jars
88 | JAR_FILE=${LIB_DIR}/tigase-server*.jar
89 | fi
90 |
91 | for j in ${TIGASE_HOME}/${JAR_FILE} ; do
92 | if [ -f ${j} ] ; then
93 | TIGASE_JAR=${j}
94 | break
95 | fi
96 | done
97 |
98 | if [ -z ${TIGASE_JAR} ] ; then
99 | echo "TIGASE_HOME is not set."
100 | echo "Please set it to correct value before starting the sever."
101 | exit 1
102 | fi
103 |
104 | if [ -z "${TIGASE_CONSOLE_LOG}" ] ; then
105 | if [ ! -d "logs" ] ; then
106 | mkdir logs
107 | fi
108 | if [ -w "${TIGASE_HOME}/logs/" ] ; then
109 | TIGASE_CONSOLE_LOG="${TIGASE_HOME}/logs/tigase-console.log"
110 | else
111 | TIGASE_CONSOLE_LOG="/dev/null"
112 | fi
113 | fi
114 |
115 | if [ -z "${TIGASE_PID}" ] ; then
116 | if [ -w "${TIGASE_HOME}/logs/" ] ; then
117 | TIGASE_PID="${TIGASE_HOME}/logs/tigase.pid"
118 | else
119 | if [ -w "/var/run/" ] ; then
120 | TIGASE_PID="/var/run/tigase.pid"
121 | else
122 | TIGASE_PID="/var/tmp/tigase.pid"
123 | fi
124 | fi
125 | fi
126 |
127 | [[ -z "${TIGASE_RUN}" ]] && \
128 | TIGASE_RUN="tigase.server.XMPPServer ${TIGASE_OPTIONS}"
129 |
130 | [[ -z "${JAVA}" ]] && JAVA="${JAVA_HOME}/bin/java"
131 |
132 | [[ -z "${CLASSPATH}" ]] || CLASSPATH="${CLASSPATH}:"
133 |
134 | CLASSPATH="${CLASSPATH}${TIGASE_JAR}"
135 |
136 | CLASSPATH="`ls -d ${TIGASE_HOME}/${LIB_DIR}/*.jar 2>/dev/null | grep -v wrapper | tr '\n' :`${CLASSPATH}"
137 |
138 | LOGBACK="-Dlogback.configurationFile=$TIGASE_HOME/etc/logback.xml"
139 |
140 | export GNUPGHOME
141 |
142 | if [ -n "${OSGI}" ] && ${OSGI} ; then
143 | TIGASE_CMD="${JAVA} ${JAVA_OPTIONS} ${LOGBACK} -jar ${JAR_FILE}"
144 | else
145 | TIGASE_CMD="${JAVA} ${JAVA_OPTIONS} ${LOGBACK} -cp ${CLASSPATH} ${TIGASE_RUN}"
146 | fi
147 |
148 | cd "${TIGASE_HOME}"
149 |
150 | case "${1}" in
151 | start)
152 | echo "Starting Tigase: "
153 |
154 | if [ -f ${TIGASE_PID} ] && kill -0 $(<${TIGASE_PID}) 2>/dev/null
155 | then
156 | echo "Already Running!!"
157 | exit 1
158 | fi
159 |
160 | echo "STARTED Tigase `date`" >> ${TIGASE_CONSOLE_LOG}
161 |
162 | nohup sh -c "exec $TIGASE_CMD >>${TIGASE_CONSOLE_LOG} 2>&1" >/dev/null &
163 | echo $! > $TIGASE_PID
164 | echo "Tigase running pid="`cat $TIGASE_PID`
165 | ;;
166 |
167 | stop)
168 | PID=`cat $TIGASE_PID 2>/dev/null`
169 | if [ -z "$PID" ] ; then
170 | echo "Tigase is not running."
171 | exit 0
172 | fi
173 | echo "Shutting down Tigase: $PID"
174 |
175 | kill $PID 2>/dev/null
176 | for ((i=1; i <= 10; i++)) ; do
177 | if ps -p $PID > /dev/null ; then
178 | echo "$i. Waiting for the server to terminate..."
179 | sleep 1
180 | else
181 | echo "$i. Tigase terminated."
182 | break
183 | fi
184 | done
185 |
186 | if ps -p $PID > /dev/null ; then
187 | echo "Forcing the server to terminate."
188 | kill -9 $PID 2>/dev/null
189 | fi
190 | rm -f $TIGASE_PID
191 | echo "STOPPED `date`" >>${TIGASE_CONSOLE_LOG}
192 | ;;
193 |
194 | restart)
195 | $0 stop $2
196 | sleep 5
197 | $0 start $2
198 | ;;
199 |
200 | clearrestart)
201 | $0 stop $2
202 | sleep 5
203 | $0 clear $2
204 | sleep 2
205 | $0 start $2
206 | ;;
207 |
208 | clear)
209 | LOGBACK="${TIGASE_HOME}/logs"`date "+%Y-%m-%d--%H:%M:%S"`
210 | echo "Clearing logs, moving backup to " ${LOGBACK}
211 | mkdir -p ${LOGBACK}
212 | mv "${TIGASE_HOME}/logs"/* ${LOGBACK}/
213 | if [ -n "${OSGI}" ] && ${OSGI} ; then
214 | echo "Clearing osgi cache"
215 | rm -rf "${TIGASE_HOME}/felix-cache"/*;
216 | fi
217 | ;;
218 |
219 | run)
220 | echo "Running Tigase: "
221 |
222 | if [ -f $TIGASE_PID ]
223 | then
224 | echo "Already Running!!"
225 | exit 1
226 | fi
227 |
228 | sh -c "exec $TIGASE_CMD"
229 | ;;
230 |
231 | check|status)
232 | echo "Checking arguments to Tigase: "
233 | echo "OSGI = $OSGI"
234 | echo "TIGASE_HOME = $TIGASE_HOME"
235 | echo "TIGASE_JAR = $TIGASE_JAR"
236 | echo "TIGASE_PARAMS = $TIGASE_PARAMS"
237 | echo "TIGASE_RUN = $TIGASE_RUN"
238 | echo "TIGASE_PID = $TIGASE_PID"
239 | echo "TIGASE_OPTIONS = $TIGASE_OPTIONS"
240 | echo "JAVA_OPTIONS = $JAVA_OPTIONS"
241 | echo "JAVA = $JAVA"
242 | echo "JAVA_CMD = $JAVA_CMD"
243 | echo "CLASSPATH = $CLASSPATH"
244 | echo "TIGASE_CMD = $TIGASE_CMD"
245 | echo "TIGASE_CONSOLE_LOG = $TIGASE_CONSOLE_LOG"
246 | echo
247 |
248 | if [ -f ${TIGASE_PID} ] && kill -0 $(<${TIGASE_PID}) 2>/dev/null
249 | then
250 | echo "Tigase running pid="`cat ${TIGASE_PID}`
251 | exit 0
252 | fi
253 | exit 1
254 | ;;
255 | zap)
256 | rm -f $TIGASE_PID
257 | ;;
258 |
259 | *)
260 | usage
261 | ;;
262 | esac
263 |
--------------------------------------------------------------------------------
/vagrant/.gitignore:
--------------------------------------------------------------------------------
1 | /local.properties
2 |
--------------------------------------------------------------------------------
/vagrant/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | Vagrant.configure(2) do |config|
5 | config.vm.box = "debian/jessie64"
6 |
7 | # Disable automatic box update checking. If you disable this, then
8 | # boxes will only be checked for updates when the user runs
9 | # `vagrant box outdated`. This is not recommended.
10 | # config.vm.box_check_update = false
11 |
12 | # Use this hostname for the VM
13 | config.vm.hostname = "prime.kontalk.net"
14 |
15 | # Create a forwarded port mapping which allows access to a specific port
16 | # within the machine from a port on the host machine. In the example below,
17 | # accessing "localhost:8080" will access port 80 on the guest machine.
18 | config.vm.network "forwarded_port", guest: 5222, host: 15222
19 |
20 | # Create a private network, which allows host-only access to the machine
21 | # using a specific IP.
22 | #config.vm.network "private_network", ip: "192.168.33.10"
23 |
24 | # Bridged network
25 | #config.vm.network "public_network"
26 |
27 | config.vm.provider "virtualbox" do |vb|
28 | # Display the VirtualBox GUI when booting the machine
29 | vb.gui = true
30 | # Customize the amount of memory on the VM:
31 | vb.memory = "512"
32 | end
33 | #
34 | # View the documentation for the provider you are using for more
35 | # information on available options.
36 |
37 | # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
38 | # such as FTP and Heroku are also available. See the documentation at
39 | # https://docs.vagrantup.com/v2/push/atlas.html for more information.
40 | # config.push.define "atlas" do |push|
41 | # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
42 | # end
43 |
44 | # install system
45 | config.vm.provision :shell, :inline => <<-SH
46 | cd /vagrant
47 | ./bootstrap.sh
48 | SH
49 |
50 | # install Kontalk
51 | config.vm.provision :shell, privileged: false, :inline => <<-SH
52 | cd /vagrant
53 | ./install.sh
54 | SH
55 |
56 | # TODO rename vagrant to DEFAULT_USER
57 | #config.vm.provision :shell, path: "finish.sh", privileged: false
58 | end
59 |
--------------------------------------------------------------------------------
/vagrant/bootstrap.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source setup/functions.sh
4 |
5 | if [ ! -f local.properties ]; then
6 | echo "local.properties not found!"
7 | exit 1
8 | fi
9 |
10 | source local.properties
11 |
12 | # save our primary and only host name
13 | export PRIMARY_HOSTNAME=$(get_default_hostname)
14 | echo "Using primary hostname: ${PRIMARY_HOSTNAME}"
15 |
16 | # install system stuff
17 | source setup/system.sh
18 |
19 | # install Java 8
20 | source setup/java8.sh
21 |
22 | # install MySQL
23 | source setup/mysql.sh
24 |
25 | # install rng for increased entropy
26 | if [ ! -f /etc/default/rng-tools ];
27 | then
28 | apt_install rng-tools
29 | [ ! -f /etc/default/rng-tools ] && exit 1
30 | echo "HRNGDEVICE=/dev/urandom" >>/etc/default/rng-tools
31 | restart_service rng-tools
32 | fi
33 |
34 | # global environment variables
35 | cp export.sh /etc/profile.d/globalenv.sh
36 |
37 | # cleanup
38 | source setup/cleanup.sh
39 |
40 | # custom script
41 | [ -x data/custom.sh ] && source data/custom.sh
42 |
43 | # last step: setup ssh
44 | #source setup/ssh.sh
45 |
--------------------------------------------------------------------------------
/vagrant/conf/fail2ban/jail.local:
--------------------------------------------------------------------------------
1 | # Fail2Ban configuration file for Kontalk
2 |
3 | # JAILS
4 |
5 | [ssh]
6 | maxretry = 7
7 | bantime = 3600
8 |
9 | [ssh-ddos]
10 | enabled = true
11 |
12 | [sasl]
13 | enabled = true
14 |
--------------------------------------------------------------------------------
/vagrant/conf/init.properties.dist:
--------------------------------------------------------------------------------
1 | # Default Kontalk configuration, fine for most configurations
2 |
3 | # XMPP host where you're serving your Kontalk instance
4 | # Kontalk extensions support one virtual host only for now
5 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/host=@HOSTNAME@
6 | # Virtual hosts served by this instance (must match the above)
7 | --virt-hosts=@HOSTNAME@
8 | # Administrator JID (must be in the above domain)
9 | --admins=admin@@HOSTNAME@
10 |
11 | # Fingerprint of the GPG server key
12 | sess-man/plugins-conf/fingerprint=@FINGERPRINT@
13 |
14 | # The global network domain (do not change this if you want to participate in the Kontalk global network)
15 | sess-man/plugins-conf/network-domain=kontalk.net
16 |
17 | # Database configuration (the two db-uri parameters must be identical)
18 | --user-db=mysql
19 | --user-db-uri=jdbc:mysql://localhost:3306/@DBNAME@?user=@DBUSER@&password=@DBPASS@&useUnicode=true&characterEncoding=UTF-8
20 | sess-man/plugins-conf/db-uri=jdbc:mysql://localhost:3306/@DBNAME@?user=@DBUSER@&password=@DBPASS@&useUnicode=true&characterEncoding=UTF-8
21 |
22 | # Registration provider configuration
23 | # Dummy provider configuration
24 | # It will always accept 123456 as a valid verification code
25 | # Good for a remote test server
26 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/providers[s]=dummy=org.kontalk.xmppserver.registration.DummyProvider
27 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/dummy-sender=123456
28 |
29 | # Endpoints configuration
30 | # All endpoints must declare a clientCertCA pointing to a valid certificate chain file
31 | # (any CA chain will do, it won't actually be used but Tigase won't work without it)
32 |
33 | # Client endpoint configuration
34 | --c2s-ports=5222
35 | c2s/clientCertCA=trusted.pem
36 |
37 | # Websocket endpoint configuration
38 | message-router/components/msg-receivers/ws2s.active[B]=false
39 | ws2s/connections/5290/socket=ssl
40 | ws2s/clientCertCA=trusted.pem
41 |
42 | # BOSH endpoint configuration
43 | message-router/components/msg-receivers/bosh.active[B]=false
44 | bosh/connections/5280/socket=ssl
45 | bosh/clientCertCA=trusted.pem
46 |
47 | # S2S endpoint configuration (comment to disable XMPP federation)
48 | --s2s-ports=5269
49 |
50 | # Enabled plugins, comma-separated
51 | # prefixed with a minus (-) means not loaded, prefixed with nothing or with a plus (+) means loaded.
52 | --sm-plugins=-amp,-message-carbons,-jabber:iq:auth,-jabber:iq:register,-jabber:iq:privacy,-jabber:iq:last,-msgoffline,-urn:xmpp:blocking,-urn:xmpp:csi:0,+message,+msgoffline2,+presence:urn:xmpp:pubkey:2,+kontalk:jabber:iq:register,+kontalk:jabber:iq:roster,+urn:xmpp:pubkey:2,+kontalk:urn:xmpp:blocking,+kontalk:urn:xmpp:csi:0,+kontalk:jabber:iq:last
53 |
54 | # Comment these to revert to default logging
55 | --debug=server,xmpp.impl
56 | --debug-packages=org.kontalk
57 |
58 | # External components. Do not change the default names!
59 | # --comp-xxx parameter pairs follow a numbering order
60 | # whenever you delete/comment or insert a component, remember to fix the numbering!!
61 |
62 | # Network component
63 | # enables server list commands. Particularly needed if participating in a global network
64 | --comp-name-1=network
65 | --comp-class-1=org.kontalk.xmppserver.NetworkComponent
66 |
67 | # Phone number lookup component
68 | # enables discovery of contacts in the local/global network by their phone numbers
69 | --comp-name-2=probe
70 | --comp-class-2=org.kontalk.xmppserver.probe.ProbeComponent
71 |
72 | --comp-name-3=multicast
73 | --comp-class-3=org.kontalk.xmppserver.ExtendedAddressing
74 |
75 | # External XMPP component protocol
76 | # needed for HttpFileUploadComponent
77 | #--comp-name-4=ext
78 | #--comp-class-4=tigase.server.ext.ComponentProtocol
79 | # these must match HttpFileUploadComponent configuration
80 | #--external=media.prime.kontalk.net:secret:listen:5270
81 |
82 | # Internal parameters
83 | # the following properties must not be changed unless you really know what you're doing
84 | basic-conf/auth-repo-params/sasl-mechs=EXTERNAL
85 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/factory=org.kontalk.xmppserver.auth.KontalkSaslServerFactory
86 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/mechanism-selector=org.kontalk.xmppserver.auth.KontalkMechanismSelector
87 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/callbackhandler-EXTERNAL=org.kontalk.xmppserver.auth.KontalkCertificateCallbackHandler
88 | sess-man/plugins-conf/presence-state/extended-presence-processors=org.kontalk.xmppserver.presence.PublicKeyPresence
89 | c2s/processors[s]=urn:xmpp:sm:3=org.kontalk.xmppserver.KontalkIOProcessor
90 | message-router/components/msg-receivers/amp.active[B]=false
91 | --vhost-anonymous-enabled=false
92 | --vhost-tls-required=false
93 | --hardened-mode=true
94 | config-type=--gen-config-def
95 |
--------------------------------------------------------------------------------
/vagrant/data/bash_aliases:
--------------------------------------------------------------------------------
1 | # ~/.bash_aliases - Aliases definitions
2 |
3 | # enable color support of ls and also add handy aliases
4 | if [ "$TERM" != "dumb" ]; then
5 | eval "`dircolors -b`"
6 | alias ls='ls --color=auto'
7 | #alias dir='ls --color=auto --format=vertical'
8 | #alias vdir='ls --color=auto --format=long'
9 | fi
10 |
11 | # some more ls aliases
12 | alias ll='ls -l'
13 | alias la='ls -A'
14 | alias l='ls -CF'
15 | alias lsd='ls -d */'
16 |
17 | alias cd..='cd ..'
18 | alias ..='cd ..'
19 | alias du='du -h'
20 | alias df='df -h'
21 |
--------------------------------------------------------------------------------
/vagrant/data/custom.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source setup/functions.sh
4 |
5 | echo "Removing unused packages"
6 | apt_get_quiet remove --purge bash-completion
7 |
8 | echo "Customizing environment"
9 | cp data/bash_aliases /root/.bash_aliases
10 | cp /etc/bash.bashrc /root/.bashrc
11 | tools/editconf.py /root/.bashrc \
12 | force_color_prompt=yes
13 |
--------------------------------------------------------------------------------
/vagrant/export.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export JAVA_HOME="/usr/lib/jvm/java-8-oracle"
4 |
--------------------------------------------------------------------------------
/vagrant/install.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source setup/functions.sh
4 |
5 | if [ ! -f local.properties ]; then
6 | echo "local.properties not found!"
7 | exit 1
8 | fi
9 |
10 | source local.properties
11 |
12 | # save our primary and only host name
13 | export PRIMARY_HOSTNAME=$(get_default_hostname)
14 | echo "Using primary hostname: ${PRIMARY_HOSTNAME}"
15 |
16 | # download and build Kontalk server
17 | source setup/tigase-kontalk.sh
18 |
19 | # create Kontalk database
20 | source setup/kontalk-database.sh
21 |
22 | # create server keys and certificate
23 | source setup/kontalk-keys.sh
24 |
25 | # configure Kontalk server
26 | source setup/kontalk-config.sh
27 |
--------------------------------------------------------------------------------
/vagrant/local.properties.dist:
--------------------------------------------------------------------------------
1 | #DISABLE_FIREWALL=1
2 | MYSQL_ROOT_PASSWORD=root
3 | MYSQL_USER_NAME=kontalk
4 | MYSQL_USER_PASSWORD=kontalk
5 | SSH_PORT=60822
6 | SWAPSIZE=1GiB
7 | TIMEZONE=Europe/Rome
8 |
--------------------------------------------------------------------------------
/vagrant/setup/cleanup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Cleanup script
3 |
4 | source setup/functions.sh
5 |
6 | echo "Cleaning up"
7 | apt_get_quiet clean
8 |
--------------------------------------------------------------------------------
/vagrant/setup/functions.sh:
--------------------------------------------------------------------------------
1 | function hide_output {
2 | # This function hides the output of a command unless the command fails
3 | # and returns a non-zero exit code.
4 |
5 | # Get a temporary file.
6 | OUTPUT=$(tempfile)
7 |
8 | # Execute command, redirecting stderr/stdout to the temporary file.
9 | $@ &> $OUTPUT
10 |
11 | # If the command failed, show the output that was captured in the temporary file.
12 | E=$?
13 | if [ $E != 0 ]; then
14 | # Something failed.
15 | echo
16 | echo FAILED: $@
17 | echo -----------------------------------------
18 | cat $OUTPUT
19 | echo -----------------------------------------
20 | exit $E
21 | fi
22 |
23 | # Remove temporary file.
24 | rm -f $OUTPUT
25 | }
26 |
27 | function apt_get_quiet {
28 | # Run apt-get in a totally non-interactive mode.
29 | #
30 | # Somehow all of these options are needed to get it to not ask the user
31 | # questions about a) whether to proceed (-y), b) package options (noninteractive),
32 | # and c) what to do about files changed locally (we don't cause that to happen but
33 | # some VM providers muck with their images; -o).
34 | #
35 | # Although we could pass -qq to apt-get to make output quieter, many packages write to stdout
36 | # and stderr things that aren't really important. Use our hide_output function to capture
37 | # all of that and only show it if there is a problem (i.e. if apt_get returns a failure exit status).
38 | if [ $(whoami) != "root" ]; then
39 | APT_PREFIX="sudo "
40 | fi
41 | DEBIAN_FRONTEND=noninteractive hide_output ${APT_PREFIX} apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" "$@"
42 | }
43 |
44 | function apt_install {
45 | # Install a bunch of packages. We used to report which packages were already
46 | # installed and which needed installing, before just running an 'apt-get
47 | # install' for all of the packages. Calling `dpkg` on each package is slow,
48 | # and doesn't affect what we actually do, except in the messages, so let's
49 | # not do that anymore.
50 | PACKAGES=$@
51 | apt_get_quiet install $PACKAGES
52 | }
53 |
54 | function get_default_hostname {
55 | # Guess the machine's hostname. It should be a fully qualified
56 | # domain name suitable for DNS. None of these calls may provide
57 | # the right value, but it's the best guess we can make.
58 | set -- $(hostname --fqdn 2>/dev/null ||
59 | hostname --all-fqdns 2>/dev/null ||
60 | hostname 2>/dev/null)
61 | printf '%s\n' "$1" # return this value
62 | }
63 |
64 | function get_publicip_from_web_service {
65 | # This seems to be the most reliable way to determine the
66 | # machine's public IP address: asking a very nice web API
67 | # for how they see us. Thanks go out to icanhazip.com.
68 | # See: https://major.io/icanhazip-com-faq/
69 | #
70 | # Pass '4' or '6' as an argument to this function to specify
71 | # what type of address to get (IPv4, IPv6).
72 | curl -$1 --fail --silent --max-time 15 icanhazip.com 2>/dev/null
73 | }
74 |
75 | function ufw_allow {
76 | if [ -z "$DISABLE_FIREWALL" ]; then
77 | # ufw has completely unhelpful output
78 | ufw allow $1 > /dev/null;
79 | fi
80 | }
81 |
82 | function restart_service {
83 | hide_output service $1 restart
84 | }
85 |
86 | function wget_verify {
87 | # Downloads a file from the web and checks that it matches
88 | # a provided hash. If the comparison fails, exit immediately.
89 | URL=$1
90 | HASH=$2
91 | DEST=$3
92 | CHECKSUM="$HASH $DEST"
93 | rm -f $DEST
94 | wget -q -O $DEST $URL || exit 1
95 | if ! echo "$CHECKSUM" | sha1sum --check --strict > /dev/null; then
96 | echo "------------------------------------------------------------"
97 | echo "Download of $URL did not match expected checksum."
98 | echo "Found:"
99 | sha1sum $DEST
100 | echo
101 | echo "Expected:"
102 | echo "$CHECKSUM"
103 | rm -f $DEST
104 | exit 1
105 | fi
106 | }
107 |
108 | function git_clone {
109 | # Clones a git repository, checks out a particular commit or tag,
110 | # and moves the repository (or a subdirectory in it) to some path.
111 | # We use separate clone and checkout because -b only supports tags
112 | # and branches, but we sometimes want to reference a commit hash
113 | # directly when the repo doesn't provide a tag.
114 | REPO=$1
115 | TREEISH=$2
116 | SUBDIR=$3
117 | TARGETPATH=$4
118 | TMPPATH=/tmp/git-clone-$$
119 | rm -rf $TMPPATH $TARGETPATH
120 | git clone -q $REPO $TMPPATH || exit 1
121 | (cd $TMPPATH; git checkout -q $TREEISH;) || exit 1
122 | mv $TMPPATH/$SUBDIR $TARGETPATH
123 | rm -rf $TMPPATH
124 | }
125 |
126 | function sql_as_root {
127 | hide_output mysql -uroot -p${MYSQL_ROOT_PASSWORD} $@
128 | }
129 |
130 | function sql_as_user {
131 | hide_output mysql -u${MYSQL_USER_NAME} -p${MYSQL_USER_PASSWORD} ${MYSQL_USER_NAME} $@
132 | }
133 |
--------------------------------------------------------------------------------
/vagrant/setup/java8.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | source setup/functions.sh
4 |
5 | if which java >/dev/null; then
6 | echo "Skipping Java installation"
7 | else
8 | echo "Installing Oracle JDK 8"
9 | echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list
10 | echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list
11 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 >/dev/null
12 | apt_get_quiet update
13 | echo debconf shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections
14 | echo debconf shared/accepted-oracle-license-v1-1 seen true | /usr/bin/debconf-set-selections
15 | apt_install -qq --yes oracle-java8-installer >/dev/null
16 | yes "" | apt_install -f
17 | fi
18 |
--------------------------------------------------------------------------------
/vagrant/setup/kontalk-config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # get GPG key fingerprint
4 | FINGERPRINT=$(gpg2 --with-colons --with-fingerprint --list-secret-keys | grep fpr | awk '{print $10}' FS=:)
5 | if [ "${FINGERPRINT}" == "" ]; then
6 | echo "GPG key not found!"
7 | exit 1
8 | fi
9 |
10 | echo "Using GPG key ${FINGERPRINT}"
11 |
12 | # export keys to file
13 | gpg2 --export ${FINGERPRINT} >${HOME}/tigase-kontalk/server-public.key
14 | gpg2 --export-secret-key ${FINGERPRINT} >${HOME}/tigase-kontalk/server-private.key
15 |
16 | # fill the servers table
17 | sql_as_user <${HOME}/tigase-kontalk/etc/init.properties
29 |
--------------------------------------------------------------------------------
/vagrant/setup/kontalk-database.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # create database if needed
4 | if [ ! -f ${HOME}/.databasesetup ];
5 | then
6 | echo "Creating database"
7 | sql_as_root </dev/null
21 |
22 | # create kontalk database objects
23 | for SCRIPT in ${HOME}/tigase-extension/data/*.sql;
24 | do
25 | sql_as_user < ${SCRIPT}
26 | done
27 |
28 | touch ${HOME}/.databasesetup
29 | fi
30 |
--------------------------------------------------------------------------------
/vagrant/setup/kontalk-keys.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # create SSL certificate if needed
4 | SSL_CERT="${HOME}/tigase-kontalk/certs/$(hostname -f).pem"
5 | if [ ! -f ${SSL_CERT} ];
6 | then
7 | echo "Generating SSL certificate"
8 | hide_output openssl req -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=$(hostname -f)" -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
9 | mkdir -p $(dirname ${SSL_CERT})
10 | cat cert.pem key.pem >${SSL_CERT} &&
11 | rm cert.pem key.pem
12 | fi
13 |
14 | # create GPG key if needed
15 | if [ ! -f ${HOME}/.gpgsetup ];
16 | then
17 | echo "Generating GPG key pair"
18 | hide_output gpg2 --batch --gen-key < /etc/timezone
8 |
9 |
10 | # ### Setup a swap file
11 | if [ -n "${SWAPSIZE}" ]; then
12 | SWAPFILE=/swapfile
13 |
14 | if [ -f "${SWAPFILE}" ]; then
15 | echo "Swap space already set"
16 | else
17 | echo "Setting up swap space"
18 | hide_output fallocate --length ${SWAPSIZE} ${SWAPFILE}
19 | hide_output mkswap ${SWAPFILE}
20 | hide_output chmod 0600 ${SWAPFILE}
21 | hide_output swapon ${SWAPFILE}
22 |
23 | # configure fstab
24 | grep -q "/swapfile" /etc/fstab ||
25 | echo "/swapfile none swap sw 0 0" >>/etc/fstab
26 | fi
27 | fi
28 |
29 |
30 | # ### Update Packages
31 |
32 | # Update system packages to make sure we have the latest upstream versions of things from Ubuntu.
33 |
34 | echo "Updating system"
35 | hide_output apt-get update
36 | apt_get_quiet dist-upgrade
37 |
38 | # ### Install System Packages
39 |
40 | # Install basic utilities.
41 | #
42 | # * haveged: Provides extra entropy to /dev/random so it doesn't stall
43 | # when generating random numbers for private keys (e.g. during
44 | # ldns-keygen).
45 | # * unattended-upgrades: Apt tool to install security updates automatically.
46 | # * cron: Runs background processes periodically.
47 | # * ntp: keeps the system time correct
48 | # * fail2ban: scans log files for repeated failed login attempts and blocks the remote IP at the firewall
49 | # * netcat-openbsd: `nc` command line networking tool
50 | # * git: we install some things directly from github
51 | # * sudo: allows privileged users to execute commands as root without being root
52 | # * coreutils: includes `nproc` tool to report number of processors, mktemp
53 | # * bc: allows us to do math to compute sane defaults
54 |
55 | echo "Installing system packages"
56 | apt_install python3 python3-dev python3-pip \
57 | netcat-openbsd wget curl git sudo coreutils bc \
58 | vim vim-scripts htop haveged \
59 | unattended-upgrades cron ntp fail2ban
60 |
61 | # ### Seed /dev/urandom
62 | #
63 | # /dev/urandom is used by various components for generating random bytes for
64 | # encryption keys and passwords:
65 | #
66 | # * TLS private key (see `ssl.sh`, which calls `openssl genrsa`)
67 | # * DNSSEC signing keys (see `dns.sh`)
68 | # * our management server's API key (via Python's os.urandom method)
69 | # * Roundcube's SECRET_KEY (`webmail.sh`)
70 | # * ownCloud's administrator account password (`owncloud.sh`)
71 | #
72 | # Why /dev/urandom? It's the same as /dev/random, except that it doesn't wait
73 | # for a constant new stream of entropy. In practice, we only need a little
74 | # entropy at the start to get going. After that, we can safely pull a random
75 | # stream from /dev/urandom and not worry about how much entropy has been
76 | # added to the stream. (http://www.2uo.de/myths-about-urandom/) So we need
77 | # to worry about /dev/urandom being seeded properly (which is also an issue
78 | # for /dev/random), but after that /dev/urandom is superior to /dev/random
79 | # because it's faster and doesn't block indefinitely to wait for hardware
80 | # entropy. Note that `openssl genrsa` even uses `/dev/urandom`, and if it's
81 | # good enough for generating an RSA private key, it's good enough for anything
82 | # else we may need.
83 | #
84 | # Now about that seeding issue....
85 | #
86 | # /dev/urandom is seeded from "the uninitialized contents of the pool buffers when
87 | # the kernel starts, the startup clock time in nanosecond resolution,...and
88 | # entropy saved across boots to a local file" as well as the order of
89 | # execution of concurrent accesses to /dev/urandom. (Heninger et al 2012,
90 | # https://factorable.net/weakkeys12.conference.pdf) But when memory is zeroed,
91 | # the system clock is reset on boot, /etc/init.d/urandom has not yet run, or
92 | # the machine is single CPU or has no concurrent accesses to /dev/urandom prior
93 | # to this point, /dev/urandom may not be seeded well. After this, /dev/urandom
94 | # draws from the same entropy sources as /dev/random, but it doesn't block or
95 | # issue any warnings if no entropy is actually available. (http://www.2uo.de/myths-about-urandom/)
96 | # Entropy might not be readily available because this machine has no user input
97 | # devices (common on servers!) and either no hard disk or not enough IO has
98 | # ocurred yet --- although haveged tries to mitigate this. So there's a good chance
99 | # that accessing /dev/urandom will not be drawing from any hardware entropy and under
100 | # a perfect-storm circumstance where the other seeds are meaningless, /dev/urandom
101 | # may not be seeded at all.
102 | #
103 | # The first thing we'll do is block until we can seed /dev/urandom with enough
104 | # hardware entropy to get going, by drawing from /dev/random. haveged makes this
105 | # less likely to stall for very long.
106 |
107 | echo "Initializing system random number generator"
108 | dd if=/dev/random of=/dev/urandom bs=1 count=32 2> /dev/null
109 |
110 | # ### Package maintenance
111 | #
112 | # Allow apt to install system updates automatically every day.
113 |
114 | cat > /etc/apt/apt.conf.d/02periodic </dev/null | grep "^port " | sed "s/port //")
139 | if [ ! -z "$_SSH_PORT" ]; then
140 | if [ "$_SSH_PORT" != "22" ]; then
141 |
142 | echo "Opening alternate SSH port ${_SSH_PORT}"
143 | ufw_allow ${_SSH_PORT}
144 |
145 | fi
146 | fi
147 |
148 | ufw --force enable;
149 | fi
150 |
151 | # ### Local DNS Service
152 |
153 | # Install a local DNS server, rather than using the DNS server provided by the
154 | # ISP's network configuration.
155 | #
156 | # We do this to ensure that DNS queries
157 | # that *we* make (i.e. looking up other external domains) perform DNSSEC checks.
158 | # We could use Google's Public DNS, but we don't want to create a dependency on
159 | # Google per our goals of decentralization. `bind9`, as packaged for Ubuntu, has
160 | # DNSSEC enabled by default via "dnssec-validation auto".
161 | #
162 | # So we'll be running `bind9` bound to 127.0.0.1 for locally-issued DNS queries
163 | # and `nsd` bound to the public ethernet interface for remote DNS queries asking
164 | # about our domain names. `nsd` is configured later.
165 | #
166 | # About the settings:
167 | #
168 | # * RESOLVCONF=yes will have `bind9` take over /etc/resolv.conf to tell
169 | # local services that DNS queries are handled on localhost.
170 | # * Adding -4 to OPTIONS will have `bind9` not listen on IPv6 addresses
171 | # so that we're sure there's no conflict with nsd, our public domain
172 | # name server, on IPV6.
173 | # * The listen-on directive in named.conf.options restricts `bind9` to
174 | # binding to the loopback interface instead of all interfaces.
175 | apt_install bind9 resolvconf
176 | tools/editconf.py /etc/default/bind9 \
177 | RESOLVCONF=yes \
178 | "OPTIONS=\"-u bind -4\""
179 | if ! grep -q "listen-on " /etc/bind/named.conf.options; then
180 | # Add a listen-on directive if it doesn't exist inside the options block.
181 | sed -i "s/^}/\n\tlisten-on { 127.0.0.1; };\n\tmax-recursion-queries 200;\n}/" /etc/bind/named.conf.options
182 | sed -i "s/listen-on-v6 { \(any;\) };/listen-on-v6 { ::1; };/" /etc/bind/named.conf.options
183 | fi
184 | if [ -f /etc/resolvconf/resolv.conf.d/original ]; then
185 | echo "Archiving old resolv.conf (was /etc/resolvconf/resolv.conf.d/original, now /etc/resolvconf/resolv.conf.original)"
186 | mv /etc/resolvconf/resolv.conf.d/original /etc/resolvconf/resolv.conf.original
187 | fi
188 |
189 | # update root servers
190 | hide_output wget -O /etc/bind/db.root "http://www.internic.net/domain/named.root"
191 |
192 | # Restart the DNS services.
193 |
194 | restart_service bind9
195 | restart_service resolvconf
196 |
197 | # ### Fail2Ban Service
198 |
199 | # Configure the Fail2Ban installation to prevent dumb bruce-force attacks against dovecot, postfix and ssh
200 | cp conf/fail2ban/jail.local /etc/fail2ban/jail.local
201 |
202 | restart_service fail2ban
203 |
--------------------------------------------------------------------------------
/vagrant/setup/tigase-kontalk.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # use production branch
4 | BRANCH="production"
5 |
6 | echo "Installing Kontalk from ${BRANCH} branch"
7 |
8 | echo "Installing system dependencies"
9 | apt_install gnupg2 libgpgme11-dev libkyotocabinet16 libkyotocabinet-dev gcc g++ maven git make
10 |
11 | # switch to home directory
12 | OLDCWD=$PWD
13 | cd
14 |
15 | # install jkyotocabinet
16 | if [ ! -f .jkyotosetup ];
17 | then
18 | wget -q http://fallabs.com/kyotocabinet/javapkg/kyotocabinet-java-1.24.tar.gz >/dev/null &&
19 | tar -xzf kyotocabinet-java-1.24.tar.gz &&
20 | cd kyotocabinet-java-1.24 &&
21 | hide_output ./configure --prefix=/usr
22 | hide_output make
23 | hide_output sudo make install
24 | cd .. &&
25 | rm -fR kyotocabinet-java-1.24 kyotocabinet-java-1.24.tar.gz &&
26 |
27 | touch .jkyotosetup
28 | fi
29 |
30 | # install Kontalk server
31 | if [ ! -d tigase-kontalk ];
32 | then
33 | echo "Installing Kontalk server"
34 | git clone -b "${BRANCH}" "https://github.com/kontalk/tigase-server" &&
35 | git clone -b "${BRANCH}" "https://github.com/kontalk/tigase-extension" &&
36 | git clone "https://github.com/kontalk/tigase-kontalk" &&
37 | cd tigase-kontalk &&
38 | hide_output mvn install
39 | ln -sf /usr/lib/libjkyotocabinet.so jars/libjkyotocabinet.so
40 | cd ..
41 | fi
42 |
43 | cd ${OLDCWD}
44 |
45 | # allow XMPP port
46 | ufw_allow xmpp-client
47 |
--------------------------------------------------------------------------------
/vagrant/tools/editconf.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | #
3 | # This is a helper tool for editing configuration files during the setup
4 | # process. The tool is given new values for settings as command-line
5 | # arguments. It comments-out existing setting values in the configuration
6 | # file and adds new values either after their former location or at the
7 | # end.
8 | #
9 | # The configuration file has settings that look like:
10 | #
11 | # NAME=VALUE
12 | #
13 | # If the -s option is given, then space becomes the delimiter, i.e.:
14 | #
15 | # NAME VALUE
16 | #
17 | # If the -c option is given, then the supplied character becomes the comment character
18 | #
19 | # If the -w option is given, then setting lines continue onto following
20 | # lines while the lines start with whitespace, e.g.:
21 | #
22 | # NAME VAL
23 | # UE
24 |
25 | import sys, re
26 |
27 | # sanity check
28 | if len(sys.argv) < 3:
29 | print("usage: python3 editconf.py /etc/file.conf [-s] [-w] [-c ] [-t] NAME=VAL [NAME=VAL ...]")
30 | sys.exit(1)
31 |
32 | # parse command line arguments
33 | filename = sys.argv[1]
34 | settings = sys.argv[2:]
35 |
36 | delimiter = "="
37 | delimiter_re = r"\s*=\s*"
38 | comment_char = "#"
39 | folded_lines = False
40 | testing = False
41 | while settings[0][0] == "-" and settings[0] != "--":
42 | opt = settings.pop(0)
43 | if opt == "-s":
44 | # Space is the delimiter
45 | delimiter = " "
46 | delimiter_re = r"\s+"
47 | elif opt == "-w":
48 | # Line folding is possible in this file.
49 | folded_lines = True
50 | elif opt == "-c":
51 | # Specifies a different comment character.
52 | comment_char = settings.pop(0)
53 | elif opt == "-t":
54 | testing = True
55 | else:
56 | print("Invalid option.")
57 | sys.exit(1)
58 |
59 | # sanity check command line
60 | for setting in settings:
61 | try:
62 | name, value = setting.split("=", 1)
63 | except:
64 | import subprocess
65 | print("Invalid command line: ", subprocess.list2cmdline(sys.argv))
66 |
67 | # create the new config file in memory
68 |
69 | found = set()
70 | buf = ""
71 | input_lines = list(open(filename))
72 |
73 | while len(input_lines) > 0:
74 | line = input_lines.pop(0)
75 |
76 | # If this configuration file uses folded lines, append any folded lines
77 | # into our input buffer.
78 | if folded_lines and line[0] not in (comment_char, " ", ""):
79 | while len(input_lines) > 0 and input_lines[0][0] in " \t":
80 | line += input_lines.pop(0)
81 |
82 | # See if this line is for any settings passed on the command line.
83 | for i in range(len(settings)):
84 | # Check that this line contain this setting from the command-line arguments.
85 | name, val = settings[i].split("=", 1)
86 | m = re.match(
87 | "(\s*)"
88 | + "(" + re.escape(comment_char) + "\s*)?"
89 | + re.escape(name) + delimiter_re + "(.*?)\s*$",
90 | line, re.S)
91 | if not m: continue
92 | indent, is_comment, existing_val = m.groups()
93 |
94 | # If this is already the setting, do nothing.
95 | if is_comment is None and existing_val == val:
96 | # It may be that we've already inserted this setting higher
97 | # in the file so check for that first.
98 | if i in found: break
99 | buf += line
100 | found.add(i)
101 | break
102 |
103 | # comment-out the existing line (also comment any folded lines)
104 | if is_comment is None:
105 | buf += comment_char + line.rstrip().replace("\n", "\n" + comment_char) + "\n"
106 | else:
107 | # the line is already commented, pass it through
108 | buf += line
109 |
110 | # if this option oddly appears more than once, don't add the setting again
111 | if i in found:
112 | break
113 |
114 | # add the new setting
115 | buf += indent + name + delimiter + val + "\n"
116 |
117 | # note that we've applied this option
118 | found.add(i)
119 |
120 | break
121 | else:
122 | # If did not match any setting names, pass this line through.
123 | buf += line
124 |
125 | # Put any settings we didn't see at the end of the file.
126 | for i in range(len(settings)):
127 | if i not in found:
128 | name, val = settings[i].split("=", 1)
129 | buf += name + delimiter + val + "\n"
130 |
131 | if not testing:
132 | # Write out the new file.
133 | with open(filename, "w") as f:
134 | f.write(buf)
135 | else:
136 | # Just print the new file to stdout.
137 | print(buf)
138 |
--------------------------------------------------------------------------------