Nginx unter macOS mittels Homebrew installieren und nutzen

Nginx wird für gewöhnlich unter Linux genutzt. Für Entwicklungszwecke kann es interessant sein Nginx unter macOS zu betreiben. Zur Installation von Nginx wird Homebrew benötigt. Homebrew ist ein Paketmanager für macOS, mit welchem viele Open-Source-Projekte unter macOS installiert werden können. Ist Homebrew installiert kann Nginx auf dem Terminal mittels:

brew install nginx

installiert werden. Standardmäßig läuft Nginx bei der Installation über Homebrew auf dem Port 8080. Hintergrund ist das der Webserver somit ohne root-Rechte bzw. ohne sudo genutzt werden kann. Wird der Port auf 80 oder generell auf einen Port kleiner 1024 gestellt, werden wieder entsprechende administrative Rechte benötigt. Soll der verwendete Port geändert werden, muss die Konfigurationsdatei angepasst werden:

nano /usr/local/etc/nginx/nginx.conf

In dieser findet sich folgender Block:

server {
  listen       8080;
  server_name  localhost;

Dort kann anschließend der Port geändert werden. Neben dem Port kann dort die Default-Location geändert werden. Dazu wird der server-Block bzw. dessen Unterblock, der location-Block angepasst:

location / {
  root /Users/seeseekey/Web;
  autoindex on;

Die root-Direktive gibt den Pfad an, welcher über den Webserver ausgeliefert wird. Die Option autoindex sorgt für das entsprechende Directory-Listing, was für Entwicklungszwecke nützlich sein kann. Gestartet und gestoppt werden kann der Service mittels:

brew services start nginx

bzw.

brew services stop nginx

Natürlich kann dies mittels restart in einem Rutsch erledigt werden:

brew services restart nginx

Anschließend kann Nginx mit der veränderten Konfiguration genutzt werden.

Maven-Repository in Eigenregie hosten

Wenn mittels Maven eine Abhängigkeit zur pom.xml-Datei, wie in folgendem Beispiel, hinzugefügt wird:

<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.26</version>
</dependency>

versucht Maven diese Abhängigkeit von Maven Central, dem zentralen Repository, zu beziehen. Es ist allerdings möglich Abhängigkeiten aus anderen Repositories zu beziehen. Dazu muss der repositories-Block zur pom.xml hinzugefügt werden.

<repositories>
	<repository>
		<id>example</id>
		<url>https://repository.example.org</url>
	</repository>
</repositories>

Aus Nutzersicht ist die Konfiguration von Maven damit erledigt. Soll ein solches Maven-Reposity aufgesetzt werden, ist dies relativ einfach möglich. Dazu wird ein Verzeichnis per HTTP über den Webserver Nginx ausgeliefert. Innerhalb dieses Verzeichnisses wird ein gesicherter Ordner erstellt, welcher über WebDAV erreicht werden kann. Die entsprechende Nginx-Konfiguration sieht für diesen Fall wie folgt aus:

server {
        listen   443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc/letsencrypt/live/repository.example.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/repository.example.org/privkey.pem;

        root /var/www/example/repository;

        server_name repository.example.org;

        location / {
                autoindex     on;
        }

        location /upload {
                dav_methods     PUT DELETE MKCOL COPY MOVE;
                dav_ext_methods   PROPFIND OPTIONS;

                dav_access    user:rw group:rw all:rw;

                create_full_put_path  on;

                autoindex     on;

                auth_basic "restricted";
                auth_basic_user_file /var/www/example/repository/upload/.htpasswd;
        }
}

Die .htpasswd-Datei, welche für die Authentifizierung benötigt wird, kann mit dem Tool htpasswd erstellt werden:

htpasswd -c .htpasswd nutzer1

Bei der Nutzung wird das gewünschte Passwort erfragt. Soll ein weiterer Nutzer hinzugefügt werden, so muss der Parameter -c entfernt werden:

htpasswd .htpasswd nutzer2

Anschließend wird die Konfiguration von Nginx mittels:

service nginx reload

aktualisiert. Danach kann WebDAV für die Ressource verwendet werden. In der pom.xml-Datei für das Projekt, welches ein Artefakt für das Repository erzeugt, wird der build-Bereich erweitert und der distributionManagment-Bereich hinzugefügt:

            </plugin>
        </plugins>
        <extensions>
            <extension>
                <groupId>org.apache.maven.wagon</groupId>
                <artifactId>wagon-webdav-jackrabbit</artifactId>
                <version>3.2.0</version>
            </extension>
        </extensions>
    </build>
    <distributionManagement>
        <repository>
            <id>example</id>
            <url>dav:https://repository.example.org/upload/</url>
            <layout>default</layout>
        </repository>
    </distributionManagement>
</project>

Im Extension-Bereich wird das Wagon-Plugin für WebDAV aktiviert. Dieses sorgt dafür das die Artefakte per WebDAV zum Repository hochgeladen werden. In dem distributionManagment-Bereich wird die WebDAV-URL definiert. Wenn nun ein:

mvn deploy

durchgeführt wird, wird dies allerdings nicht funktionieren. Hintergrund ist das der upload-Ordner per Basic authentication geschützt ist. Die Zugangsdaten für diese Authentifikation müssen noch hinterlegt werden. Natürlich werden diese nicht in der pom.xml hinterlegt, da dies aus Gründen der Sicherheit keine gute Idee wäre. Stattdessen werden die Daten in der settings.xml hinterlegt. Diese befindet sich im Pfad:

~/.m2/settings.xml

In dieser Datei wird eine server-Sektion mit den Zugangsdaten hinzugefügt:

<settings>
	<servers>
		<server>
			<id>example</id>
			<username>example</username>
			<password>password</password>
		</server>
	</servers>
</settings>

Anschließend kann das Artefakt erfolgreich mittels:

mvn deploy

in das Repository hochgeladen werden. Problematisch ist das sich die Daten nur im upload-Verzeichnis und nicht im eigentlichen Verzeichnis des Repository liegen. Zur Lösung hierfür wird ein Cronjob, im Kontext des Nutzers www-data, angelegt:

sudo -u www-data crontab -e

Ziel des Cronjobs ist es die Daten aus dem upload-Verzeichnis regelmäßig in das eigentliche Verzeichnis des Repository zu kopieren:

*/5  *    * * *   cp /var/www/example/repository/upload/* /var/www/example/repository/ -r

Damit wird alle 5 Minuten der Inhalt des uploadVerzeichnisses in das Repository kopiert. Ein Verschieben kann leider nicht durchgeführt werden, da die Metadaten beim jeden Deployment von Maven eingelesen werden und erweitert werden. Hier könnten Optimierungen durchgeführt werden, so das alle Dateien bis auf die Metadaten verschoben werden. Soll ein nicht öffentliches Repository erstellt werden, kann auf den zusätzlichen upload-Ordner verzeichnet werden und das Hauptverzeichnis selber per WebDAV befüllt werden. So lange die Zugangsdaten für den Server in der settings.xml-Datei hinterlegt sind, können seitens Maven die entsprechenden Artefakte bezogen werden.

WebDAV unter Nginx einrichten

Der freie Webserver Nginx beherrscht nicht nur das gewöhnliche Ausliefern von Daten über HTTP und HTTPS, sondern verfügt daneben über weitere Module. Mit einem dieser Module kann WebDAV für eine Ressource bereitgestellt werden.

WebDAV steht dabei für Web-based Distributed Authoring and Versioning und basiert auf HTTP. Über WebDAV können Dateien im Internet bereitgestellt werden. Unter anderem ist WebDAV deshalb so interessant weil es die gleichen Ports wie HTTP nutzt und somit in den seltensten Fällen blockiert wird. Im ersten Schritt sollte das benötigte Modul installiert werden:

apt install libnginx-mod-http-dav-ext

Zur Nutzung des Modules für WebDAV muss die Konfiguration der jeweiligen Seite unter /etc/nginx/sites-available/ angepasst werden. In diesem Beispiel wäre dies:

nano /etc/nginx/sites-available/example

Zur dieser Konfigurationsdatei wird folgende Konfiguration hinzugefügt:

server {
        listen   443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;

        root /var/www/example;

        server_name example.org;

        location / {
                dav_methods     PUT DELETE MKCOL COPY MOVE;
                dav_ext_methods   PROPFIND OPTIONS;
                dav_access    user:rw group:rw all:rw;

                autoindex     on;
        }
}

In diesem Fall wird für die Domain example.org die WebDAV-Unterstützung aktiviert. Dateien können hierbei ohne weitere Authentifizierung herunter- und hochgeladen werden. Soll WebDAV abgesichert werden, so geschieht das über den Basic authentication. Dazu wird dem location-Part folgendes hinzugefügt:

auth_basic "restricted";
auth_basic_user_file /var/www/example/.htpasswd;

Die .htpasswd-Datei kann mit dem Tool htpasswd erstellt werden:

htpasswd -c .htpasswd nutzer1

Bei der Nutzung wird das gewünschte Passwort erfragt. Soll ein weiterer Nutzer hinzugefügt werden, so muss der Parameter -c entfernt werden:

htpasswd .htpasswd nutzer2

Anschließend wird die Konfiguration von Nginx mittels:

service nginx reload

aktualisiert. Danach kann WebDAV für die Ressource verwendet werden.

Java-Bibliothek für das Minecraft-Protokoll

Wenn sich der Minecraft-Client mit dem entsprechenden Server verbindet, so kommunizieren diese über ein festgelegtes Protokoll. Mit einer eigenen Implementation dieses Protokolls ist es möglich sich mit einem Minecraft-Server zu verbinden und entsprechende Aktionen durchzuführen. Zum Beispiel könnte diese Möglichkeit genutzt werden um einen Bot für Minecraft zu schreiben. Eine solche Implementation des Minecraft-Protokolls ist die Java-Bibliothek MCProtocolLib von Steven Smith.

Central City auf meinem eigenen Minecraft-Server

Ein minimales Beispiel, für den Login auf dem Server (basierend auf einem Unit-Test der Bibliothek), mit besagter Bibliothek könnte dabei wie folgt aussehen:

public class SimpleBot {

    private static final String HOST = "example.org";
    private static final int PORT = 25565;
    private static final Proxy PROXY = Proxy.NO_PROXY;
    private static final Proxy AUTH_PROXY = Proxy.NO_PROXY;
    private static final String USERNAME = ";
    private static final String PASSWORD = "password";

    public static void main(String[] args) throws FileNotFoundException, RequestException {

        MinecraftProtocol protocol = new MinecraftProtocol(USERNAME, PASSWORD);
        Client client = new Client(HOST, PORT, protocol, new TcpSessionFactory(PROXY));
        client.getSession().setFlag(MinecraftConstants.AUTH_PROXY_KEY, AUTH_PROXY);

        client.getSession().addListener(new SessionAdapter() {
            @Override
            public void packetReceived(PacketReceivedEvent event) {
                if(event.getPacket() instanceof ServerJoinGamePacket) {
                    event.getSession().send(new ClientChatPacket("Hello, World!"));
                } else if(event.getPacket() instanceof ServerChatPacket) {
                    Message message = event.getPacket().getMessage();
                    System.out.println("Received Message: " + message.getFullText());
                    if(message instanceof TranslationMessage) {
                        System.out.println("Received Translation Components: " + Arrays.toString(((TranslationMessage) message).getTranslationParams()));
                    }

                    event.getSession().disconnect("Finished");
                }
            }

            @Override
            public void disconnected(DisconnectedEvent event) {
                System.out.println("Disconnected: " + Message.fromString(event.getReason()).getFullText());
                if(event.getCause() != null) {
                    event.getCause().printStackTrace();
                }
            }
        });

        client.getSession().connect();
    }
}

In diesem Beispiel wird sich mit dem Server verbunden und nach erfolgreicher Verbindung eine Chatnachricht gesendet. Danach loggt sich der Bot wieder aus. Der Quelltext der Bibliothek ist auf GitHub zu finden. Das Projekt ist unter der MIT-Lizenz lizenziert und damit freie Software.

Wo befinden sich die Crontab-Dateien?

Wenn Cronjobs auf einem Linux-System angelegt werden sollen, so geschieht dies meist mit dem Befehl:

crontab -e

Damit wird die Crontab-Datei des aktuellen Nutzern in einem Editor geöffnet. Leider verschleiert der Befehl den Ort an dem die eigentlichen Crontab-Dateien liegen. Dies ist z.B. dann interessant wenn ein Backup der Cronjobs eingespielt werden soll. Die entsprechenden Crontab-Dateien befinden sich hierbei im Ordner:

/var/spool/cron/crontabs

Für jeden Nutzer existiert dort eine Datei mit dem entsprechenden Nutzernamen, in welchem die Cronjobs hinterlegt sind. Meistens wird ein solches Backup nach dem Befehl:

crontab -r

benötigt werden. Dieses Befehl löscht die Crontab-Datei des aktuellen Nutzers. Leider ist die E-Taste ein direkter Nachbar der R-Taste. Dies führt dazu das die Crontab-Datei beim Versuch sie zu bearbeiten, bedingt durch einen kleinen Vertipper, ohne Rückfrage gelöscht wird.