No edit summary |
|||
Line 66: | Line 66: | ||
For more information about tag-scanner, please see the [https://gitea.vm.nurd.space/NURDspace/tag-scanner/src/branch/main/README.md README.md] file in the tag-scanner repository. | For more information about tag-scanner, please see the [https://gitea.vm.nurd.space/NURDspace/tag-scanner/src/branch/main/README.md README.md] file in the tag-scanner repository. | ||
== Door controller == | |||
To control the EAN420 lock, we use a rest api which triggers the correct pins on the gpio ports of spacenanny. The rest api is secured with mutual-tls certificates based on a PKI infrastructure which is dedicated for the lock system. Access will only be granted if the api is presented with a valid certificate with an allowed Subject. | |||
The api itself consists of three different parts globally. The Lock classes provide access to setup, status, open and close functionality for the lock. These classes will detect if the code is running on a raspberry pi. If this is not the case, a mock class will be loaded which simulates the working of the lock. This allows development of the software without access to physical hardware. | |||
On top of the Lock classes is a Server class. This provides a flask-based api with built-in TLS support. Once a client connects, the validity of the presented certificate is checked, and a check is performed to determine if the Subject of the certificate is allowed to submit requests. Once the client is authenticated, it can call the `/v1/doorlock` using the GET and PUT methods. | |||
If you call `GET /v1/doorlock`, the system will fetch the current state of the lock and return this as json: | |||
{"locked": true} | |||
If you call `PUT /v1/doorlock`, the lock will be disengaged for a configurable amount of time, after which the door lock is re-engaged. This is a blocking call, and it will return a blob of json containing the status of the operation: | |||
{"status": true} |
Revision as of 22:08, 20 January 2024
Summary
Our current access control system was not all that flexible, and we want to switch to a new system.
Architecture
Door scanner
We have an Asia-Teco scanner speaks the wiegand protocol (details can be found here: https://a.aliexpress.com/_EJOtZhl). It has the following pinout on the cable:
VCC (+12V) | Red |
GND | Black |
D0/RX/4R+ | Green |
D1/TX/4R- | White |
LED | Blue |
BEEP | Yellow |
WG26/WG34 | Gray |
An arduino combined with a stepup converter is used to translate the wiegand protocol to a text-based format which is exposed over usb-serial. The code for this can be found here: https://github.com/NURDspace/spacenanny-wiegand-arduino. This is linked together according to the following schematic, using a long piece of cat5 as the cable:
This arduino is connected using USB to spacenanny, and we run the tag scanner software there (https://gitea.vm.nurd.space/NURDspace/tag-scanner).
Tag Scanner
To read out the scanner, we use the tag-scanner software [1]. Once started, it will connect to the serial port on which the scanner is connected and wait for the scanner to send tokens. On reception of a valid token, the token is combined with a seed, and hashed using SHA256. The hashed token is used to perform a lookup in tokens.json, which contains a mapping of token -> username. If a valid match is found, a HTTP call will be made to the door lock api to disengage the door lock. If there is no valid match, a warning will be logged and a message will be posted on mqtt.
For testing purposes, the tag-scanner has a mock class to use in place of the physical tag scanner. This will automaticallty be used if there is no usb serial device available. It will present itself as a prompt which can be used to enter a token. The following is an example of running the tag-scanner in development mode, authenticating both a valid and an invalid token:
alita [tag-scanner] >> ./tag_scanner.py INFO: Connected to localhost:1883 INFO: Scanner not found, running with a mock scanner >> s 111234 INFO: Authorized access request for r3boot, disengaging door lock INFO: Door lock has been engaged >> s 111235 WARNING: Unknown token scanned: 69747dfa5ace63e857f16a73c268ce37b668a522eb6209a8b4478f3226a5d74e >>
Furthermore, the tag-scanner will report auditing events via mqtt. The topic on which the messages is posted is '/door/access'. First, there are two messages used to signal the starting+stopping of the application:
{"host": "alita", "application": "tag-scanner", "level": "INFO", "subject": "application", "event": "starting", "timestamp": "1705766869.1188245"} {"host": "alita", "application": "tag-scanner", "level": "INFO", "subject": "application", "event": "stopping", "timestamp": "1705766870.3937583"}
When a token is found to be valid, the following message is sent:
{"host": "alita", "application": "tag-scanner", "level": "INFO", "username": "r3boot", "event": "authorized", "timestamp": "1705767030.312545"}
When an unknown token is scanned, the following message is sent. Note that the token value is salted+hashed.
{"host": "alita", "application": "tag-scanner", "level": "INFO", "token": "69747dfa5ace63e857f16a73c268ce37b668a522eb6209a8b4478f3226a5d74e", "event": "unknown_token", "timestamp": "1705767085.1585684"}
For more information about tag-scanner, please see the README.md file in the tag-scanner repository.
Door controller
To control the EAN420 lock, we use a rest api which triggers the correct pins on the gpio ports of spacenanny. The rest api is secured with mutual-tls certificates based on a PKI infrastructure which is dedicated for the lock system. Access will only be granted if the api is presented with a valid certificate with an allowed Subject.
The api itself consists of three different parts globally. The Lock classes provide access to setup, status, open and close functionality for the lock. These classes will detect if the code is running on a raspberry pi. If this is not the case, a mock class will be loaded which simulates the working of the lock. This allows development of the software without access to physical hardware.
On top of the Lock classes is a Server class. This provides a flask-based api with built-in TLS support. Once a client connects, the validity of the presented certificate is checked, and a check is performed to determine if the Subject of the certificate is allowed to submit requests. Once the client is authenticated, it can call the `/v1/doorlock` using the GET and PUT methods.
If you call `GET /v1/doorlock`, the system will fetch the current state of the lock and return this as json:
{"locked": true}
If you call `PUT /v1/doorlock`, the lock will be disengaged for a configurable amount of time, after which the door lock is re-engaged. This is a blocking call, and it will return a blob of json containing the status of the operation:
{"status": true}