Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .ort.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ resolutions:
- message: "property:advertising-clause license LicenseRef-scancode-rsa-md4 in Gradle:ee.ria.xroad:src:1.0."
reason: "LICENSE_ACQUIRED_EXCEPTION"
comment: "The LicenseRef-scancode-rsa-md4 in src/libs/iaikPkcs11Wrapper.AUTHORS is taken into account, and therefore the license conditions are satisfied."
- message: "property:advertising-clause license LicenseRef-scancode-rsa-md4 in Gradle:org.niis.xroad:x-road-core:1.0."
reason: "LICENSE_ACQUIRED_EXCEPTION"
comment: "The LicenseRef-scancode-rsa-md4 in src/libs/iaikPkcs11Wrapper.AUTHORS is taken into account, and therefore the license conditions are satisfied."
- message: "property:advertising-clause license LicenseRef-scancode-rsa-md4 in Unmanaged::X-Road:.*"
reason: "LICENSE_ACQUIRED_EXCEPTION"
comment: "The LicenseRef-scancode-rsa-md4 in src/libs/iaikPkcs11Wrapper.AUTHORS is taken into account, and therefore the license conditions are satisfied."
- message: "commercial license LicenseRef-scancode-proprietary-license in Maven:org.apache.commons:commons-compress:1.26.*"
reason: "LICENSE_ACQUIRED_EXCEPTION"
comment: "This PKWare technology is not in use, therefore license is sufficient."
Expand All @@ -196,6 +202,9 @@ resolutions:
- message: "proprietary-free license LicenseRef-verbatim-no-modifications in Maven:org.hsqldb:hsqldb:2.7.*"
reason: "NOT_MODIFIED_EXCEPTION"
comment: "The license represented by LicenseRef-verbatim-no-modifications allows redistributing without modifications. As long as the files licensed with the said license are redistributed without modifications, the condition is satisfied."
- message: "copyleft-strong license CC-BY-SA-3.0 in Unmanaged::X-Road:.*"
reason: "LICENSE_ACQUIRED_EXCEPTION"
comment: "The files meant by this license hit are not distributed with X-Road."

license_choices:
repository_license_choices:
Expand Down
31 changes: 30 additions & 1 deletion ansible/roles/xroad-ca/files/home/ca/CA/sign_req.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,36 @@ trap 'status=$?; rm -rf "lock"; exit $status' INT TERM EXIT
set -e
SER=$(cat serial)
openssl req -in $2 -inform $INFORM -out csr/${SER}.csr
openssl ca -batch -config CA.cnf -extensions $EXT -days 7300 -notext -md sha256 -in csr/${SER}.csr

function opensslCA() {
openssl ca -batch -config CA.cnf \
-extensions $EXT \
-days 7300 \
-notext \
-md sha256 \
-in csr/${SER}.csr \
"$@"
}

if [ "$1" == "auth" ]; then
subjectAltName=$(openssl req -in csr/${SER}.csr -text -noout | grep -A1 "Subject Alternative Name" | tail -n1 | sed 's/^[ \t]*//')
if [ ! -z "$subjectAltName" ]; then
extensionsOverride="
[ auth_ext ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = ${subjectAltName}
"
fi
fi

if [ ! -z "${extensionsOverride}" ]; then
opensslCA -extfile <(echo "$extensionsOverride")
else
opensslCA
fi

chmod 0664 index.txt
chmod 0664 serial
echo $SER>changed
Expand Down
77 changes: 74 additions & 3 deletions doc/Manuals/ug-ss_x-road_6_security_server_user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**X-ROAD 7**

Version: 2.101
Version: 2.102
Doc. ID: UG-SS

---
Expand Down Expand Up @@ -130,6 +130,7 @@ Doc. ID: UG-SS
| 18.06.2025 | 2.99 | ACME-related updates | Petteri Kivimäki |
| 01.07.2025 | 2.100 | Added configuration notes for external op-monitor's gRPC | Mikk-Erik Bachmann |
| 07.07.2025 | 2.101 | Added chapter on Security Server Traffic visualisation | Madis Loitmaa |
| 01.12.2025 | 2.102 | Added chapter on Security Server Connection Testing | Eneli Reimets |

## Table of Contents <!-- omit in toc -->

Expand Down Expand Up @@ -247,9 +248,12 @@ Doc. ID: UG-SS
- [14.1 Diagnostics Overview](#141-diagnostics-overview)
- [14.1.1 Examine Security Server services status information](#1411-examine-security-server-services-status-information)
- [14.1.2 Examine Security Server Java version information](#1412-examine-security-server-java-version-information)
- [14.3.3 Examine Security Server encryption status information](#1433-examine-security-server-encryption-status-information)
- [14.1.3 Examine Security Server encryption status information](#1413-examine-security-server-encryption-status-information)
- [14.1.4 Download diagnostics report](#1414-download-diagnostics-report)
- [14.2 Security Server Traffic](#142-security-server-traffic)
- [14.3 Security Server Connection Testing](#143-security-server-connection-testing)
- [14.3.1 Testing the connection to the Central Server](#1431-testing-the-connection-to-the-central-server)
- [14.3.2 Testing the connection to other Security Servers](#1432-testing-the-connection-to-other-security-servers)
- [15 Operational Monitoring](#15-operational-monitoring)
- [15.1 Operational Monitoring Buffer](#151-operational-monitoring-buffer)
- [15.1.1 Stopping the Collecting of Operational Data](#1511-stopping-the-collecting-of-operational-data)
Expand Down Expand Up @@ -2498,6 +2502,7 @@ Click on **DIAGNOSTICS** in the **Navigation tabs**.
Diangostics view contains the following tabs:
- **Overview** – overview of the Security Server status information
- **Traffic** – visual overview of the Security Server traffic
- **Connection Testing** – test connectivity to the Central Server and other Security Servers

### 14.1 Diagnostics Overview

Expand Down Expand Up @@ -2553,7 +2558,7 @@ The status colors indicate the following:
- **Red indicator** – Security Server's java version number isn't supported
- **Green indicator** – Security Server's java version number is supported

#### 14.3.3 Examine Security Server encryption status information
#### 14.1.3 Examine Security Server encryption status information

**Backup encryption status**

Expand Down Expand Up @@ -2616,6 +2621,72 @@ By default, the page displays all the requests handled during the last 7 days. T
- **Exchange role** - the role of this Security Server in the message exchange. The options are "Producer" and "Consumer".
- **Status** - the status of the message exchange. The options are "Success" and "Failure".

### 14.3 Security Server Connection Testing

The "Connection Testing" tab in the Diagnostics page allows testing connectivity from the Security Server to the Central Server and other Security Servers.

The page is divided into three logical blocks:
- Central Server
- Other Security Server
- Management Security Server

Each block contains predefined tests that validate communication with the corresponding service. Test results include a status indicator ("Green" or "Red") and a detailed message to assist troubleshooting.

A **Test** button next to each row allows re-running the specific connection test.

## 14.3.1 Testing the connection to the Central Server

This block allows verifying that the Security Server can reach the Central Server and download the configuration necessary for normal operation.

**Global Configuration Download**

Tests ports `80` and `443` to verify that the Global Configuration can be downloaded from the Central Server. If the Central Server is clustered, then all clustered node addresses are included in the test. For federated instances, if the `configuration-client.allowed-federations` property is enabled, the configuration download URLs for the allowed federated instances are also included. Note that even if the global configuration contains multiple federated instances, not all of them may be enabled on the Security Server.

✔ `Everything ok` — indicates that the Central Server global configuration access via `HTTP`/`HTTPS` on ports `80`/`443` is reachable.

Examples of error messages:
- `Connection error, unknown host - cs: Name or service not known` — the Central Server hostname cannot be resolved. Check DNS configuration.
- `IO error - (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException...` — the Security Server doesn't trust the CA that issued Central Server's TLS certificate. The root certificate of the CA that was used to issue Central Server's TLS certificate must be added to the Security Server's Java truststore. For the guidelines on Publish global configuration over HTTPS, please refer to [UG-SEC](ug-sec_x_road_security_hardening.md).

**Authentication Certificate Registration Service**

Tests connectivity to the Central Server on port `4001` (used by the registration service and must be accessible by every Security Server registered to the ecosystem).

✔ `Everything ok` — indicates that the Authentication Certificate Registration Service is reachable and that the Security Server’s authentication certificate has been added. However, only the existence of the authentication certificate is checked, not its validity.

Examples of error messages:
- `Connection error, unknown host - cs: Name or service not known | Certificate not found - No auth cert found` — the Central Server hostname cannot be resolved, and the Security Server has no authentication certificate added.
- `Certificate not found - No auth cert found` — there are no connection issues, but the Security Server's authentication certificate has not been added.

## 14.3.2 Testing the connection to other Security Servers

This block enables testing communication with any other Security Server in the same X-Road instance (or federated instances). The functionality uses the `listMethods` meta service to test communication with other Security Servers. Passing the test requires that the target Security Server allows incoming connections to ports `5500` and `5577` from the source Security Server.

Field descriptions:
- **Source Client** — a list of members and subsystems registered on the client Security Server that can be used as a Source Client.
- **REST/SOAP** - the protocol (`REST` or `SOAP`) that's used to complete the connection test.
- **Target Instance** - the X-Road instance where the Target Client is registered. This can be the same instance where the Source Client is registered or a federated instance.
- **Target Client** - a list of clients registered on other Security Servers. Also, clients registered on the same Security Server with the Source Client are included to allow local testing. If federation is enabled and federated instances exist in the configuration, registered clients of federated instances are included as well.
- **Target Security Server** — a list of Security Servers where the Target Client is registered. If the Target Client is registered on multiple Security Servers, all of them are listed for selection.

✔ `Everything ok` — indicates that there are no network, configuration, or certificate issues preventing communication between the two Security Server client.

Examples of error messages:
- `server.clientproxy.ssl_authentication_failed - Security server has no valid authentication certificate`.

## 14.3.3 Testing the connection to Management Security Server

This block tests communication with the Management Security Server, including capability to send management requests (such as client register, client disable, ...).

Field descriptions:
- **Source Client** - the owner member of the client Security Server.
- **REST/SOAP** - `SOAP` since management services only support `SOAP`.
- **Target Instance** - the same instance where the Source Client is registered.
- **Target Client** - the subsystem providing the management services.
- **Target Security Server** - if management services are registered on multiple Security Servers, the user is able to select the desired target Security Server.

✔ `Everything ok` - indicates that there are no network, configuration, or certificate issues preventing communication with the management Security Server.

## 15 Operational Monitoring

**Operational monitoring data** contains data about request exchange (such as the ID-s of the client and the service, various attributes of the message read from the message header, request and response timestamps, SOAP sizes etc.) of the X-Road Security Server(s).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,25 @@
import org.niis.xroad.opmonitor.api.OpMonitoringData;
import org.niis.xroad.opmonitor.api.StoreOpMonitoringDataRequest;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.time.Duration;
import java.time.Instant;
import java.util.List;

import static java.net.NetworkInterface.getNetworkInterfaces;
import static java.util.Collections.list;
import static java.net.NetworkInterface.networkInterfaces;

@Slf4j
public class OpMonitoringDataProcessor {
private static final ObjectWriter OBJECT_WRITER = JsonUtils.getObjectWriter();
private static final String NO_ADDRESS_FOUND = "No suitable IP address is bound to network interfaces";

private static final String NO_ADDRESS_FOUND = "No suitable IP address is bound to the network interface ";
private static final String NO_INTERFACE_FOUND = "No non-loopback network interface found";
private static final ObjectWriter OBJECT_WRITER = JsonUtils.getObjectWriter();
private static final Duration IP_RESOLUTION_CACHE_DURATION = Duration.ofMinutes(10);

private String ipAddress;
private Instant ipAddressLastResolutionAt;

String prepareMonitoringMessage(List<OpMonitoringData> dataToProcess) throws JsonProcessingException {
StoreOpMonitoringDataRequest request = new StoreOpMonitoringDataRequest();
Expand All @@ -62,30 +66,31 @@ String prepareMonitoringMessage(List<OpMonitoringData> dataToProcess) throws Jso

String getIpAddress() {
try {
if (ipAddress == null) {
NetworkInterface ni = list(getNetworkInterfaces()).stream()
.filter(OpMonitoringDataProcessor::isNonLoopback)
.findFirst()
.orElseThrow(() -> XrdRuntimeException.systemInternalError(NO_INTERFACE_FOUND));

Exception addressNotFound = XrdRuntimeException.systemInternalError(NO_ADDRESS_FOUND + ni.getDisplayName());

ipAddress = list(ni.getInetAddresses()).stream()
.filter(addr -> !addr.isLinkLocalAddress())
.findFirst()
.orElseThrow(() -> addressNotFound)
.getHostAddress();

if (ipAddress == null) {
throw addressNotFound;
}
if (ipAddress != null && ipAddressLastResolutionAt != null
&& !ipAddressLastResolutionAt.isBefore(Instant.now().minus(IP_RESOLUTION_CACHE_DURATION))) {
return ipAddress;
}

ipAddress = networkInterfaces()
.filter(OpMonitoringDataProcessor::isNonLoopback)
.filter(OpMonitoringDataProcessor::hasAnyUsableAddress)
.min(OpMonitoringDataProcessor::compareNetworkInterfaces)
.stream()
.flatMap(NetworkInterface::inetAddresses)
.filter(OpMonitoringDataProcessor::isUsableAddress)
.min(OpMonitoringDataProcessor::compareInetAddresses)
.map(InetAddress::getHostAddress)
.orElseThrow(OpMonitoringDataProcessor::addressNotFoundException);

ipAddressLastResolutionAt = Instant.now();

return ipAddress;
} catch (Exception e) {
log.error("Cannot get IP address of a non-loopback network interface", e);

return "0.0.0.0";
// keep the failed resolution cached for resolution cache duration as well.
ipAddressLastResolutionAt = Instant.now();
ipAddress = "0.0.0.0";
return ipAddress;
}
}

Expand All @@ -96,4 +101,27 @@ private static boolean isNonLoopback(NetworkInterface ni) {
throw XrdRuntimeException.systemException(e);
}
}

private static boolean hasAnyUsableAddress(NetworkInterface ni) {
return ni.inetAddresses().anyMatch(OpMonitoringDataProcessor::isUsableAddress);
}

private static int compareNetworkInterfaces(NetworkInterface ni1, NetworkInterface ni2) {
return Integer.compare(ni1.getIndex(), ni2.getIndex());
}

private static boolean isUsableAddress(InetAddress addr) {
return !addr.isLoopbackAddress()
&& !addr.isLinkLocalAddress()
&& addr.getHostAddress() != null;
}

private static int compareInetAddresses(InetAddress a1, InetAddress a2) {
// prefer IPv4 addresses
return Boolean.compare(a1 instanceof Inet6Address, a2 instanceof Inet6Address);
}

private static XrdRuntimeException addressNotFoundException() {
return XrdRuntimeException.systemInternalError(NO_ADDRESS_FOUND);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,21 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.niis.xroad.confclient.core;
package org.niis.xroad.proxy.core.opmonitoring;

/**
* A small interface for deciding if the additional configuration for a given X-Road instance should be downloaded.
* Not downloading the configuration prevents federation with that instance for this security server.
*/
public interface FederationConfigurationSourceFilter {
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import static org.junit.Assert.assertNotNull;

@Slf4j
public class OpMonitoringDataProcessorTest {
@Test
public void verifyIpAddressIsResolved() {
OpMonitoringDataProcessor proc = new OpMonitoringDataProcessor();

String ip = proc.getIpAddress();

/**
* @param instanceIdentifier the instance identifier of an existing federation partner
* @return <code>true</code> if the configuration should be downloaded, <code>false</code> otherwise
*/
boolean shouldDownloadConfigurationFor(String instanceIdentifier);
assertNotNull(ip);
}
}
Loading
Loading