├── .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 | --------------------------------------------------------------------------------