Troubleshooting

In case of problem, you should enable additional logging by setting the LOG_LEVEL=info environment variable, as explained in the documentation. InterDiode checks if the current configuration is valid, and these checks can also be manually run with the check command.

A process does not start

The different services wait for the database and the Redis cache to be prepared before they can start. This action is performed with the configuration apply command.

The connection between the black and red instances does not work

Obviously, the ability to transfer data from the black side to the red side is critical in InterDiode. However, using a diode makes troubleshooting transmission issues more difficult. Nevertheless, here are the steps to follow and the points to check in case of a problem.

  • Deactivate the send process on the black side and the receive process on the red side, to avoid data loss during the troubleshooting process.

  • Be sure that the port is allowed in the firewall configuration on both the black and red servers.

  • Be sure that the port and the protocol is declared in the compose.yaml if Docker compose is used (by default, only the TCP is open),

  • If the transfers use UDP connections, be sure that a direct link (through a data diode) exists to the red server, that the MAC address of the red server is known by the black server, and that it is injected into the ARP cache of the host machine before using the integrated air gap protocol. This must be done on the host machine, not in the Docker container.

  • Be sure that the black server can reach the red server on the configured port, and that the red server can receive data on this port: no firewall should block the connection.

    On the red machine, you can start a basic UDP or TCP server with docker run --rm -it interdiode/interdiode python3 to check if the black machine can reach it:

    import socket
    port = 15124
    # Replace 15124 with the port configured in RED_DESTINATION_PORT
    # when using UDP connections:
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.bind(("0.0.0.0", port))
        print("Waiting for a message...")
        data, addr = sock.recvfrom(1024)
        print(f"Received from {addr} : {data.decode(errors='replace')}")
    # when using TCP connections:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server.bind(("0.0.0.0", port))
        server.listen()
        conn, addr = server.accept()
        with conn:
            print("Waiting for a message...")
            data = conn.recv(4096)
            print(f"Received {len(data)} bytes : {data!r}")
    

    On the black machine, launch a UDP transmitter with docker run --rm -it interdiode/interdiode python3 to check if the black machine can reach it:

    import socket
    addr, port = "8.8.8.8", 15124
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: sock.sendto(b"Hello from the black side.", (addr, port))
    print("Message sent.")
    # Replace 8.8.8.8 with the IP address configured in RED_DESTINATION_IP
    # Replace 15124 with the port configured in RED_DESTINATION_PORT
    import socket
    addr, port = "8.8.8.8", 15124
    with socket.create_connection((addr, port)) as sock: sock.sendall(b"Hello from the black side.")
    print("Message sent.")
    
  • If the connection is working, you can use dedicated InterDiode tools to check the connection and the data transfer, as explained in the documentation.

    On the red machine, you can use the docker run --rm -it interdiode interdiode-ctl hairgap --skip-db -v 2 test-receive --count 1 --port 15124 command to receive a single file.

    On the black machine, you can use the docker run --rm -it interdiode interdiode-ctl hairgap --skip-db -v 2 test-send --port 15124 <filename> command to send an arbitrary file.

Large files cannot be uploaded

If the file is too large, it may be rejected by the web server or the reverse proxy. Large files can be uploaded by increasing the timeout of the HTTP server with the --http-timeout option of the run http command. The reverse proxy must also be configured to accept larger files (for example with Nginx use the client_max_body_size 10G; setting) and to wait for the server response by increasing the timeout for reading responses from the proxied server (for example with Nginx use the proxy_read_timeout 600s; setting).

Workers are killed while processing updates

During package updates, a large amount of information is temporarily kept in memory to reduce the number of database queries. It is necessary to keep already processed packages in memory when dependency handling is enabled. This helps speed up the update process, but it can result in high memory usage. If a very large number of packages is required, for example more than 10,000, workers may be killed by the operating system if there is not enough memory.