Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x509: certificate signed by unknown authority Hyperledger Fabric Community #1274

Open
Mathavan1122 opened this issue Nov 30, 2024 · 0 comments

Comments

@Mathavan1122
Copy link

I am trying to create a new peer which will be running in a different host machine. As I have the express js server with the react in my main host, all works fine with using the admin and client certs before i register the new peer. After the peer is registered and running, all the certs giving error saying like below.

    2024-11-30 03:39:29.297 UTC 0043 WARN [endorser] Validate -> access denied channel=mychannel txID=d9ae6785 error="the supplied identity is not valid: x509: certificate signed by unknown authority (possibly because of \"x509: ECDSA verification failure\" while trying to verify candidate authority certificate \"ca.org1.example.com\")" errorVerbose="x509: certificate signed by unknown authority (possibly because of \"x509: ECDSA verification failure\" while trying to verify candidate authority certificate \"ca.org1.example.com\")\nthe supplied identity is not valid" identity="(mspid=Org1MSP subject=CN=PATIENT_1,OU=org1+OU=client+OU=patient,O=Hyperledger,ST=North Carolina,C=US issuer=CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US serialnumber=730594218695751457221358860858176473267678034244)"
    2024-11-30 03:39:29.297 UTC 0044 WARN [endorser] ProcessProposal -> Failed to preProcess proposal error="error validating proposal: access denied: channel [mychannel] creator org unknown, creator is malformed"
point to note would be it works fine with admin certs, I am running my peers in docker containers.

peer0

    peer0.org1.example.com:
    container_name: peer0.org1.example.com
    image: hyperledger/fabric-peer:latest
    labels:
      service: hyperledger-fabric
    environment:
      - FABRIC_CFG_PATH=/etc/hyperledger/peercfg
      - FABRIC_LOGGING_SPEC=INFO
      #- FABRIC_LOGGING_SPEC=DEBUG
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_PROFILE_ENABLED=false
      - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
      # Peer specific variables
      - CORE_PEER_ID=peer0.org1.example.com
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
      - CORE_PEER_GOSSIP_USELEADERELECTION=false
      - CORE_PEER_GOSSIP_ORGLEADER=true
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp
      - CORE_OPERATIONS_LISTENADDRESS=peer0.org1.example.com:9444
      - CORE_METRICS_PROVIDER=prometheus
      - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG={"peername":"peer0org1"}
      - CORE_CHAINCODE_EXECUTETIMEOUT=300s
    volumes:
      - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com:/etc/hyperledger/fabric
      - peer0.org1.example.com:/var/hyperledger/production
    working_dir: /root
    command: peer node start
    ports:
      - 7051:7051
      - 9444:9444
    networks:
      - test

new peer i am running some automation to register and enroll

    #!/bin/bash

# Set the root directory to the raspberry-pi folder
ROOTDIR=$(cd "$(dirname "$0")" && pwd)
export PATH=${ROOTDIR}/bin:$PATH
export FABRIC_CFG_PATH=${ROOTDIR}/config

# Automatically detect the laptop's IP address
laptop_ip=$(hostname -I | awk '{print $1}')
echo "Detected laptop IP: $laptop_ip"

# Get Raspberry Pi details from the user
read -p "Enter Raspberry Pi IP: " pi_ip
read -p "Enter SSH username for Raspberry Pi: " ssh_user
read -p "Enter PATIENT_ID for the patient: " patient_id

# Check if the CA container exists and is running
container_name=$(docker ps --filter "name=ca_org1" --format "{{.Names}}")
if [ -z "$container_name" ]; then
    echo "Error: No CA container named 'ca_org1' found. Ensure it is running."
    exit 1
fi

# Check if the peer container exists and is running
container_peer=$(docker ps --filter "name=peer0.org1.example.com" --format "{{.Names}}")
if [ -z "$container_peer" ]; then
    echo "Error: No container named 'peer0.org1.example.com' found. Ensure it is running."
    exit 1
fi

# Delete old certificates to ensure new ones are generated
echo "Deleting old CA certificates inside the Docker container..."
docker exec $container_name sh -c "rm -rf /etc/hyperledger/fabric-ca-server/*.pem"

# Modify CA configuration inside Docker to add SAN for IPs
echo "Modifying CA configuration inside the Docker container..."
docker exec $container_name sh -c "
  sed -i '/hosts:/a \ \ \ \ - $laptop_ip' /etc/hyperledger/fabric-ca-server/fabric-ca-server-config.yaml
  cat /etc/hyperledger/fabric-ca-server/fabric-ca-server-config.yaml
"
# Restart the CA server to apply the new configuration
echo "Restarting the CA server..."
docker restart ${container_name}

# Add a delay to ensure the certificate is available
echo "Waiting for CA server to generate the certificate..."
sleep 5

echo "Copying CA certificate from Docker container to host..."
if ! docker cp ${container_name}:/etc/hyperledger/fabric-ca-server/ca-cert.pem ./ca-cert.pem; then
    echo "docker cp failed. Using fallback with docker exec..."
    docker exec ${container_name} cat /etc/hyperledger/fabric-ca-server/ca-cert.pem > ./ca-cert.pem
fi

if [ ! -f ./ca-cert.pem ]; then
    echo "Error: Failed to copy CA certificate from the container."
    exit 1
fi

# Enroll the admin user on the CA server
echo "Enrolling admin user..."
docker exec $container_name fabric-ca-client enroll \
  -u https://admin:adminpw@localhost:7054 --caname ca-org1 \
  --tls.certfiles /etc/hyperledger/fabric-ca-server/ca-cert.pem \
  --enrollment.profile tls 

# Determine the next available peer index
peer_index=0
while docker exec $container_name fabric-ca-client identity list --id "peer${peer_index}" \
  --tls.certfiles /etc/hyperledger/fabric-ca-server/ca-cert.pem 2>&1 | grep -q "Name:"; do
    echo "Found existing peer${peer_index}. Incrementing index..."
    peer_index=$((peer_index + 1))
done

peer_name="peer${peer_index}"
echo "Next peer to be registered: ${peer_name}"

# Register the new peer with the CA server
echo "Registering ${peer_name} with CA server..."
if ! docker exec $container_name fabric-ca-client register \
  --caname ca-org1 \
  --id.name "${peer_name}" --id.secret peerpw --id.type peer \
  --tls.certfiles ./ca-cert.pem; then
    echo "Error: Failed to register ${peer_name} with the CA server."
    exit 1
fi

# Create the channel if it doesn't exist
if [ ! -f ../first-network/channel-artifacts/mychannel.block ]; then
    echo "Creating channel..."
    peer channel create -o orderer.example.com:7050 -c mychannel -f ../first-network/channel-artifacts/mychannel.tx
else
    echo "Channel already exists. Skipping channel creation."
fi

# Setup directories and transfer files on Raspberry Pi
echo "Setting up directories on Raspberry Pi..."
ssh $ssh_user@$pi_ip <<EOF
  mkdir -p ~/remote-monitoring/{bin,builders,config,chaincode,scripts,tls,channel-artifacts,msp,tlsca}
  mkdir -p ~/remote-monitoring/msp/[email protected]
EOF

# Transfer necessary files to the Raspberry Pi
echo "Transferring files to Raspberry Pi..."
scp -r ./bin ./builders ./config ./config ca-cert.pem \
    $ssh_user@$pi_ip:~/remote-monitoring/
scp ../first-network/channel-artifacts/mychannel.block \
    $ssh_user@$pi_ip:~/remote-monitoring/channel-artifacts/
scp ./docker-compose-peer.yaml \
    $ssh_user@$pi_ip:~/remote-monitoring/
scp ../first-network/patient.tar.gz \
    $ssh_user@$pi_ip:~/remote-monitoring/chaincode/
scp -r ../first-network/organizations/peerOrganizations/org1.example.com/msp/* \
    $ssh_user@$pi_ip:~/remote-monitoring/msp/
scp ./server.js \
    $ssh_user@$pi_ip:~/server/
scp -r ../first-network/organizations/peerOrganizations/org1.example.com/tlsca \
    $ssh_user@$pi_ip:~/remote-monitoring/

# Create the .env file on Raspberry Pi with the peer index
ssh $ssh_user@$pi_ip <<EOF
echo "CA_SERVER_IP=${laptop_ip}" > ~/remote-monitoring/.env
echo "PEER_INDEX=${peer_index}" >> ~/remote-monitoring/.env
rm ~/server/.env
echo "PATIENT_ID=${patient_id}" >> ~/server/.env
EOF

# Create the network.sh script on the Raspberry Pi
ssh $ssh_user@$pi_ip <<EOF
  chmod +x ~/remote-monitoring/bin/*

  cat > ~/remote-monitoring/scripts/network.sh << 'END_OF_NETWORK_SCRIPT'
#!/bin/bash

docker stop \$(docker ps -a)
docker rm -fv \$(docker ps -aq)

raspberry_ip=\$(hostname -I | awk '{print \$1}')
echo "Registering \${raspberry_ip} "

# Load variables from .env file
if [ ! -f ~/remote-monitoring/.env ]; then
    echo "Error: .env file not found."
    exit 1
fi

export CA_SERVER_IP=\$(grep -oP '(?<=CA_SERVER_IP=)\S+' ~/remote-monitoring/.env)
peer_index=\$(grep -oP '(?<=PEER_INDEX=)\S+' ~/remote-monitoring/.env)

peer_id="peer\${peer_index}"  # Identity used during registration
peer_name="peer\${peer_index}.org1.example.com"
container_name="\${peer_name}"
api_key=\$(openssl rand -hex 16)

echo "PEER_NAME=\${peer_name}" >> ~/server/.env
echo "API_KEY=\${api_key}" >> ~/server/.env

echo "Setting up \${peer_name}..."

export PATH=~/remote-monitoring/bin:\$PATH
export FABRIC_CFG_PATH=~/remote-monitoring/config
export FABRIC_CA_CLIENT_HOME=~/remote-monitoring/msp/\${peer_name}

if [ -z "\$CA_SERVER_IP" ]; then
    echo "Error: CA_SERVER_IP is not set in the .env file."
    exit 1
fi
  
echo "Enrolling \${peer_name} with CA server at \${CA_SERVER_IP}..."
fabric-ca-client enroll -u "https://\${peer_id}:peerpw@\${CA_SERVER_IP}:7054" \
  --caname ca-org1 \
  --tls.certfiles ~/remote-monitoring/ca-cert.pem \
  -M ~/remote-monitoring/msp/\${peer_name} \
  --csr.hosts "\${peer_name},\${CA_SERVER_IP},\${raspberry_ip},localhost"

CA_SERVER_IP_DASH="\${CA_SERVER_IP//./-}"

# Create the config.yaml file
cat > ~/remote-monitoring/msp/\${peer_name}/config.yaml <<END_CONFIG
NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/\${CA_SERVER_IP_DASH}-7054-ca-org1.pem
    OrganizationalUnitIdentifier: client
  PeerOUIdentifier:
    Certificate: cacerts/\${CA_SERVER_IP_DASH}-7054-ca-org1.pem
    OrganizationalUnitIdentifier: peer
  AdminOUIdentifier:
    Certificate: cacerts/\${CA_SERVER_IP_DASH}-7054-ca-org1.pem
    OrganizationalUnitIdentifier: admin
  OrdererOUIdentifier:
    Certificate: cacerts/\${CA_SERVER_IP_DASH}-7054-ca-org1.pem
    OrganizationalUnitIdentifier: orderer
END_CONFIG

# Second enrollment specifically for TLS
fabric-ca-client enroll -u "https://\${peer_id}:peerpw@\${CA_SERVER_IP}:7054" \
  --caname ca-org1 \
  --tls.certfiles ~/remote-monitoring/ca-cert.pem \
  -M ~/remote-monitoring/msp/\${peer_name}/tls \
  --enrollment.profile tls \
  --csr.hosts "\${peer_name},\${CA_SERVER_IP},\${raspberry_ip},localhost"

# Copy TLS materials to required locations with specific names
cp ~/remote-monitoring/msp/\${peer_name}/tls/tlscacerts/* ~/remote-monitoring/msp/\${peer_name}/tls/ca.crt
cp ~/remote-monitoring/msp/\${peer_name}/tls/signcerts/* ~/remote-monitoring/msp/\${peer_name}/tls/server.crt
cp ~/remote-monitoring/msp/\${peer_name}/tls/keystore/* ~/remote-monitoring/msp/\${peer_name}/tls/server.key

# Copy TLS materials to required locations with specific names
cp ~/remote-monitoring/msp/\${peer_name}/tls/tlscacerts/* ~/remote-monitoring/tls/ca.crt
cp ~/remote-monitoring/msp/\${peer_name}/tls/signcerts/* ~/remote-monitoring/tls/server.crt
cp ~/remote-monitoring/msp/\${peer_name}/tls/keystore/* ~/remote-monitoring/tls/server.key

# Ensure required Docker image is available
required_image="hyperledger/fabric-peer:latest"
echo "Checking for required Docker image: \$required_image"

if ! docker image inspect "\$required_image" &> /dev/null; then
    echo "Required image \$required_image not found. Pulling..."
    docker pull "\$required_image" || { echo "Failed to pull \$required_image"; exit 1; }
else
    echo "Image \$required_image already exists."
fi

echo "Starting \${peer_name} using Docker Compose..."
PEER_NAME=\${peer_name} RASPBERRY_IP=\${raspberry_ip} SERVER_IP=\${CA_SERVER_IP} docker-compose -f ~/remote-monitoring/docker-compose-peer.yaml up -d || { echo "Failed to start \${peer_name}"; exit 1; }

sleep 10

echo "Joining \${peer_name} to the channel..."
docker exec \${container_name} peer channel join -b /remote-monitoring/channel-artifacts/mychannel.block

#Install chaincode on the peer
echo "Installing chaincode..."
docker exec \${container_name} peer lifecycle chaincode install /remote-monitoring/chaincode/patient.tar.gz

EOF

# Execute the network setup on the Raspberry Pi
echo "Executing network setup on Raspberry Pi..."
ssh $ssh_user@$pi_ip "bash ~/remote-monitoring/scripts/network.sh"

echo "Peer${peer_index} setup complete!"

docker compose for the new peer

  version: '2'
   services:
     peer:
       container_name: ${PEER_NAME}
       image: hyperledger/fabric-peer:latest
       environment:
         - FABRIC_LOGGING_SPEC=DEBUG
         - CORE_PEER_ID=${PEER_NAME}
         - CORE_PEER_ADDRESS=${PEER_NAME}:7051
         - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
         - CORE_PEER_CHAINCODEADDRESS=${PEER_NAME}:7052
         - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
         - CORE_CHAINCODE_BUILDER=hyperledger/fabric-nodeenv:latest
         - CORE_PEER_LOCALMSPID=Org1MSP
         - CORE_PEER_TLS_ENABLED=true
         - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp
         - FABRIC_CFG_PATH=/etc/hyperledger/fabric/config
         - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/msp/${PEER_NAME}/tls/server.crt
         - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/msp/${PEER_NAME}/tls/server.key
         - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/msp/${PEER_NAME}/tls/ca.crt
   
         # CouchDB settings
         - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
         - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
         - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
         - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
   
         # Gossip settings
         - CORE_PEER_GOSSIP_USELEADERELECTION=false
         - CORE_PEER_GOSSIP_ORGLEADER=true
         - CORE_PEER_GOSSIP_EXTERNALENDPOINT=${PEER_NAME}:7051
         - CORE_PEER_GOSSIP_BOOTSTRAP=192.168.1.81:7051
         - CORE_PEER_GOSSIP_SKIPHANDSHAKE=false
   
         # Orderer settings
         - ORDERER_URL=${SERVER_IP}:7050  # Using IP instead of hostname
   
       volumes:
         - /var/run/docker.sock:/var/run/docker.sock
         - $HOME/remote-monitoring:/etc/hyperledger/fabric
         - $HOME/remote-monitoring:/remote-monitoring
         - $HOME/remote-monitoring/msp:/etc/hyperledger/fabric/msp
   
       command: peer node start
       ports:
         - 7051:7051
         - 7052:7052
       depends_on:
         - couchdb
       networks:
         - test
       extra_hosts:
         - "orderer.example.com:${SERVER_IP}"
         - "peer0.org1.example.com:${SERVER_IP}"
         - "peer0.org2.example.com:${SERVER_IP}"
   
     couchdb:
       container_name: couchdb
       image: couchdb:3.3.3
       environment:
         - COUCHDB_USER=admin
         - COUCHDB_PASSWORD=adminpw
       ports:
         - 5984:5984
       networks:
         - test
   
   networks:
     test:
       name: fabric_test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant