Config wireguard with csf

Config wireguard with csf

csfpre.sh

CSF blocks Wireguard traffic, so we need to add some rules to iptables. Here are the instructions on how to do it.

Create a csfpre.sh file in the CSF path, for example, /etc/csf/csfpre.sh.
csfpre.sh adds iptable rules to CSF before it launches.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# iptables -A INPUT -p all -m set --match-set hkip src -j ACCEPT

iptables -A INPUT -i wg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -o ens3 -j ACCEPT
iptables -A FORWARD -i ens3 -o wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.7.0.2/24 -o ens3 -j MASQUERADE

# For ipv6, opional
ip6tables -A INPUT -i wg0 -j ACCEPT
ip6tables -A OUTPUT -o wg0 -j ACCEPT
ip6tables -A FORWARD -i wg0 -o ens3 -j ACCEPT
ip6tables -A FORWARD -i ens3 -o wg0 -j ACCEPT
ip6tables -t nat -A POSTROUTING -s fddd:2c4:2c4:2c4::2/64 -o ens3 -j MASQUERADE

en3 is your network interface
10.7.0.2/24 and fddd:2c4:2c4:2c4::2/64 is your wireguard internal ip.

Don’t forget to give permission to the script: chmod +x /etc/csf/csfpre.sh.

Finally, run:

csf -ra

wg0 configuration

add the follow line to the wg0.conf

1
2
PostUp = iptables -w -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -w -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -w -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -w -t nat -D POSTROUTING -o ens3 -j MASQUERADE

Bitcoin implementation in typescript

Introduction

I am responsible for the transaction part in a group project about blockchain and bitcoin, and here is my code. Just for archive.

library

Bitcoin is using elliptic and secp256k1

1
2
3
4
import { SHA256 } from 'crypto-js';

var EC = require('elliptic').ec;
var ec = new EC('secp256k1');
1
2
3
4
5
6
7
8
9
10
11
12
export class Signature {
static sign(priKey: string, msg: string): string {
const key = ec.keyFromPrivate(priKey, 'hex');
const signature = key.sign(msg).toDER();
return signature;
}

static verify(pubKey: string, sig: string, msg: string): boolean {
const key = ec.keyFromPublic(pubKey, 'hex');
return key.verify(msg, sig);
}
}

Class in a Transaction

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

export class RegularTxIn extends TxIn {
txOutId: string;
txOutIndex: number;
signature: string;

constructor(txOutId: string, txOutIndex: number, priKey) {
super();
this.txOutId = txOutId;
this.txOutIndex = txOutIndex;
this.signature = this.createSig(priKey, this.msgHash());
}

createSig(priKey: string, msg: string): string {
return Signature.sign(priKey, msg);
}

msgHash(): string {
return SHA256(SHA256(this.txOutId + this.txOutIndex)).toString();
}
}

export class CoinbaseTxIn extends TxIn {
public blockHeight: number;

constructor(blockHeight: number) {
super();
this.blockHeight = blockHeight;
}
}

export class RegularTxIn extends TxIn {
txOutId: string;
txOutIndex: number;
signature: string;

constructor(txOutId: string, txOutIndex: number, priKey) {
super();
this.txOutId = txOutId;
this.txOutIndex = txOutIndex;
this.signature = this.createSig(priKey, this.msgHash());
}

createSig(priKey: string, msg: string): string {
return Signature.sign(priKey, msg);
}

msgHash(): string {
return SHA256(SHA256(this.txOutId + this.txOutIndex)).toString();
}
}

export class CoinbaseTxIn extends TxIn {
public blockHeight: number;

constructor(blockHeight: number) {
super();
this.blockHeight = blockHeight;
}
}

export class TxOut {
address: string; //public key
amount: number;

constructor(address: string, amount: number) {
this.address = address;
this.amount = amount;
}
}

export class UTXO {
txId: string;
txOut: TxOut;
txIndex: number;

constructor(txId: string, txOut: TxOut, txIndex: number) {
this.txId = txId;
this.txOut = txOut;
this.txIndex = txIndex;
}
}

Transaction Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
export class Transaction {
type: string;
id: string;
txIns: TxIn[];
txOuts: TxOut[];

constructor(ins: TxIn[], outs: TxOut[]) {
this.txIns = ins;
this.txOuts = outs;
this.id = this.setId();
}

setId(): string {
let txInContent: string;
if (this instanceof RegularTx) {
txInContent = this.txIns
.map((regularTxIn: RegularTxIn) => regularTxIn.txOutId + regularTxIn.txOutIndex)
.reduce((a, b) => a + b, '');
} else {
txInContent = this.txIns
.map((coinbaseTxIn: CoinbaseTxIn) => coinbaseTxIn.blockHeight)
.reduce((a, b) => a + b, '');
}

const txOutContent: string = this.txOuts
.map((txOuts: TxOut) => txOuts.address + txOuts.amount)
.reduce((a, b) => a + b, '');

return SHA256(SHA256(txInContent + txOutContent)).toString();
}

public static createRegularTx(
senderPubKey: string,
senderPriKey: string,
receiverPubKey: string,
receiveAmount: number,
fee: number,
) {
const utxo = this.findUTXO(senderPubKey);
let sumUTXO = 0;
const txIns = [];
const txOuts = [];
let i = 0;
utxo.forEach((val) => {
//the sum of UTXO of a pubkey
sumUTXO += val.amount;
// Create input object for each UTXO, sign the input by user private key
i++;
txIns.push(new RegularTxIn(val.id, i, senderPriKey));
});
const totalAmountToSpend = receiveAmount + fee;
if (sumUTXO < totalAmountToSpend) {
// Not enough money
return; //exception
}
for (let n = 0; n < txIns.length; n++) {
// verify the input by signature
const checker = Signature.verify(utxo[i].address, txIns[i].signature, txIns[i].msgHash());
if (!checker) {
return; //exception
}
}
//Create out put to receiver by PP2K
txOuts.push(new TxOut(receiverPubKey, receiveAmount));
//return change to the sender
const change = sumUTXO - receiveAmount - fee;
if (change > 0) {
txOuts.push(new TxOut(senderPubKey, change));
}
const tx = new Transaction(txIns, txOuts);
// tx.setId()
return tx;
}

public static findUTXO(senderPubKey) {
const allBlock = [];
const allTxOut = [];
const allTxIn = [];
allBlock.forEach((block) => {
const txs = block.txs;
txs.forEach((tx) => {
const txOuts = tx.txOuts;
txOuts.forEach((out) => {
if (out.address == senderPubKey) {
allTxOut.push(out);
}
});
});
});
return [];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
export class RegularTx extends Transaction {
type: 'regular';
txIns: RegularTxIn[];

constructor(ins: RegularTxIn[], outs: TxOut[]) {
super(ins, outs);
}
}

export class CoinBaseTx extends Transaction {
type: 'coinbase';
txIns: CoinbaseTxIn[];

constructor(ins: CoinbaseTxIn, outs: TxOut[]) {
super([ins], outs);
}
}

Create Transaction and UTXO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
public async createTx(
senderPubKey: string,
senderPriKey: string,
receiverPubKey: string,
receiveAmount: number,
fee: number,
) {
const utxos = await this.getUXTO(senderPubKey);
let sumUTXO = 0;

const txIns = utxos.map((tx) => {
sumUTXO += tx.txOut.amount;
return new RegularTxIn(tx.txId, tx.txIndex, senderPriKey);
});

const txOuts = [];

const totalAmountToSpend = receiveAmount + fee;

if (sumUTXO < totalAmountToSpend) {
// Not enough money
throw new Error('Insufficient Balance'); //exception
}

for (let i = 0; i < txIns.length; i++) {
// verify the input by signature
// TODO: check if utxos[i].txOut.address is correct or not
const checker = Signature.verify(utxos[i].txOut.address, txIns[i].signature, txIns[i].msgHash());

if (!checker) {
throw new Error('Invalid txIns'); //exception
}
}

//Create out put to receiver by PP2K
txOuts.push(new TxOut(receiverPubKey, receiveAmount));
//return change to the sender
const change = sumUTXO - receiveAmount - fee;
txOuts.push(new TxOut(senderPubKey, change));

const tx = new RegularTx(txIns, txOuts);
tx.setId();

this.broadcast(tx);
await this.transactionPoolService.addTransaction(tx);

return tx;
}

public async getAllUTXO(): Promise<UTXO[]> {
const outs: UTXO[] = [];
// loop all the blocks
for (let i = 0; i < this.blockService.getBlockHeight(); i++) {
const currentBlockHash = this.blockService.getBlockHash(i);
const currentBlock = await this.blockService.getBlock(currentBlockHash);
const currentTx = currentBlock.data.transactions; // need to convert to list of Transaction

// loop all the transaction
currentTx.forEach((currentTx) => {
const txID = currentTx.id;
const txOuts = currentTx.txOuts;
const txIns = currentTx.txIns;

// Create UTXO object for each TxOutPut, push to UTXO
txOuts.forEach((txOut, i) => {
outs.push(new UTXO(txID, txOut, i)); // create UTXO obj that store tx, txid and index
});

// Remove the spent money
txIns.forEach((tx) => {
if (tx instanceof RegularTxIn) {
const outID = tx.txOutId;
const outIndex = tx.txOutIndex;
const indexOfTx = outs.findIndex((obj) => {
return obj.txId == outID && obj.txIndex == outIndex;
});

if (indexOfTx >= 0) {
outs.splice(indexOfTx, 1);
}
}
});
});
}
return outs;
}

public async getUXTO(pubKey: string): Promise<UTXO[]> {
const allUtxo = await this.getAllUTXO();

return allUtxo.filter((tx) => {
return tx.txOut.address === pubKey;
});
}


IT Auditing notes 2

Operation Control

Segregation of Duties

Avoid single person could be responsible for diverse and critical functions. Otherwise, error or misappropriation could occur and not be detected in a timely manner and in normal course of business processes.

Incident handling

identify when where whole

Shadow IT: IT users at an organisation electing to use tools and services that have not been officially sanctioned by said organisation.

  • Converage - insurance?
  • Action - what to do?
  • Evidence
  • Tasks to do during recovery

Management of removable media and system documentation

Monitoring

  • audit logging
  • Clock Synchronize

Logical Controls

Concurrent Sign-on Session

can be very useful, but also a control weaknesses

Suggestion:

  • No or only few user can have concurrent
  • No more than two
  • Logged and reviewed

Remote access Control

  • Deducated leased liveness
  • VPN
  1. Identification process (username?)
  2. Authentication process (password?)
  3. Permitted/denied

Input Control

source document design - arrange fields for ease of use.

Software development Control

  • Business realization: 個system點幫到公司
  • project management
    • Cost and resource/ Deliverable/Time(Duration)
  • System development approach SDLC approaches
    • SDLC: 流水線

IT Auditing notes 1

The structure of an IT Audit

Phase 1 - Audit Planning Phase

In this phase, auditor review controls such as General Controls and application controls. After that, plan tests of controls and substantive testing procedures.

Phase 2 - Test of Control

Perform tests of control -> Evaluate Test result -> Determine degree of reliance on controls.

Phase 3 - Substantive Testing Phase

Perform Substantive Tests -> Evaluate Result -> issue audit report

PDC Control Models

Preventive 預防

Detective 監察

Corrective 執屎

Internal Control Activities

  • Independent verification
  • Transaction Authorization
  • Segregation of duties
  • Supervision
  • Audit trail provision

Physical Control

Provision of a secure area - Security perimeter

Prevent unauthorized access

  • Physical lock : Conventional keys/Electronic access badge system/cipher lock
  • Selection and design of secure areas
  • intruder detection system(Camera)
  • Sperate from 3rd party area and public area detection
  • backup
  • loading area

backup

  • Full backup
  • Incremental backup
    • Cumulative incremental: Since last full backup
    • Differentail incremental: Since last backup(any type)

Resumption programs

Hot Site - full equipped and can be operational in less than 24 hours
Cold site -
Partner with other companies

Risk Analysis

Step 1 - identify Threats and Risks

  • Threat Agents: 觸發threats既人or物 fire/hacker/employee/…
  • Weaknesses: 弱點
  • Risks: weaknesses引致既後果

Step 2 - Quantify Impact of potential Threats

Single Loss Expectancy(SLE) + Annualized frequency = Annual Loss Expectancy(ALE)

Select a counter measurement

Cost/benefits calculation:

ALE before implementing safety measure - ALE after implenting safety measure - annual cost of safeguard = value of safefuard to the company

Javascript callback promise await/async

I have been coding in JavaScript for a while now, but I realized that I didn’t have a solid understanding of how the language works. This was a surprising realization, considering how much time I spend working with it. So, to improve my skills, I decided to do some research and dive deeper into the workings of JavaScript.

JavaScript is a programming language designed to run on client-side browsers. In this context, everything related to the internet is unpredictable. For example, if an image is too large, the browser can get stuck, and that’s where callback functions come in.

A callback function is a function that’s passed as an argument to another function. It’s used to execute code asynchronously, which means that the program doesn’t stop until the function is executed entirely. The concept of a callback is that we put the functions that need time to run into a “Callback Queue” and continue running the following code. This allows us to avoid blocking the program while it waits for the function to finish running.

Another useful feature of JavaScript is the Promise object. A promise is an object that includes a resolve and reject function. The resolve function is called when the code runs successfully, while the reject function is called when the code throws an error. We use try-catch blocks to handle errors in promises.

Async/Await is another feature of JavaScript that’s used for clean code. The await keyword is used in the async function to pause the function until the Promise is resolved or rejected. We can use this feature to write asynchronous code that looks like synchronous code, which makes the code easier to read and understand.

In summary, JavaScript is a powerful language that’s essential for web development. Understanding its features, including callback functions, Promises, and Async/Await, is crucial for writing efficient and clean code.

Callback

The concept of callback is that, we put the functions that needs time to run into a “Callback Queue”, and continue run the following code.

Promise

Promise is object that include resolve and reject, for example,

1
2
3
4
5
6
7
8
9
10
11
12
13
let p = new Promise(function(resolve, reject) {
if(){
resolve();
}else{
reject;
}
})

p.then(function(){
// resolve
}).catch(function() {
// return a exception, and catch the error
})

Async Await

The await must be in the async function

1
2
3
4
5
6
7
8
9
async function getSomething(){
try{
let something = await fetch(url);
console.log(something)
}
catch( exception ){
console.log(exception)
}
}

Async await is usually the better for clean code.

leetcode Reverse Integer

Javascipt version

Javascript have the function that reverse the String, so it is pretty easy to do in js.

1
2
3
4
5
6
7
8
9
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
var y = parseInt(x.toString().split('').reverse().join(''))
if (y >= 2**31-1 || -y <= -(2**31)) return 0;
return x < 0 ? -y : y
}

Java version

This java version is not prefect through, I have not handle the overflow.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Solution {
public static int reverse(int x) {
int result = 0;
if(x == 10){return 1;}
while (x!=0){
int tail = x % 10;
int newResult = result * 10 + tail;
result =newResult;
x = x /10;
}
return result;
}
public static void main(String[] args){
System.out.print(reverse(123));
}
}

leetcode two-sum javascript

Version 1:

A simple nested for loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
for (let i = 0;i<nums.length ;i++){
let tmp = target - nums[i]
for (let j = i+1;j<nums.length;j++){
if(tmp === nums[j]){
return [i,j]
}
}
}
};

Version 2:

HashMap have much better search time than a normal queue loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
const map = new Map()

for (let i = 0; i< nums.length;i++){
const num = nums[i]
const difference = target - num

if (map.has(num)){
return [map.get(num), i]
}

map.set(difference, i)
}
};

Version 2.5 Java

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Solution {
public static int[] twoSum(int[] nums, int target) {
Map<Integer , Integer> map = new HashMap<Integer,Integer>();
for(int i = 0 ; i < nums.length ; i++) {
int targetTemp = target - nums[i];
if(map.containsKey(targetTemp)) {
return new int[] { map.get(targetTemp) , i};
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No solution");
}
}

Notes of Vue

update at 15-8-2021, review what I know about Vue

Commands of Vue

There are total 12 commands in Vue(More now, but I only know 12)

v-bind

Passing a data to html, we can use v-bind, it can pass the object and array to html:
<div v-bind:class="[activeClass, errorClass]"></div>

v-once

v-once use when the data will never change, This can be used to optimise update performance

v-model

v-text

v-html

v-on

v-if

v-else

v-show

v-for

v-pre

v-clock

Vue const create

1
2
3
4
5
6
7
8
9
10
const app = Vue.createApp({
data(){
return {
/*data here*/
}
},
methods: {
/*function here*/
},
})

or

1
2
3
4
5
6
7
8
9
10
11
12
13
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue',
//for placing data
//method can place in data, but we normally don't do that
},
methods: {
handleClick: function(){
alert("Clicked");
}
}
})

v-on

v-on can replace by @, for example v-on:click="functionName" === @click="functionName"
Used in <div>, for example:

1
2
3
<div id="app">
<button @click="hola">Say Hello</button>
</div>

v-bind

v-bind is used when attribute in vue instance is needed,
When we try to:
<a href={{website}}>some website<a> It won’t work
we need to use v-bind:
<a v-bind:href={{website}}>some website<a>
v-bind can be replaced by :
<a :href={{website}}>some website<a>

v-if, v-else

Just another if-else statement, but there are a notice able use case:

1
2
3
4
<button @click="function">
<span v-if="bool">bool is true</span>
<span v-else>bool is false</span>
</button>

v-for

To show an array of data, we need to use v-for

1
2
3
4
5
books:[
{title: 'name of the wind', author: 'abc'},
{title: 'name of the fire', author: 'onfire'},
{title: 'name of the water', author: 'bewater'},
]
1
2
3
4
5
6
<ul>
<li v-for="book in books">
<h3>{{book.title}} - {{book.author}}</h3>
</li>
</ul>

v-show

Information Security Notes 7 Wireless LAN Security

Wireless LAN configuration

  • User Mudule (UM)
  • Control Module (CM)
  • Ad Hoc WLAN(without control Mudule)
    • Without communicate with their neighbors directly

IEEE 802 Architecture

  • Physical Layer (PHY)
    • encoding/decoding of signals
  • Media Access Control (MAC)
    • Controlling access to the transmission medium is needed to provide an orderly and efficient use of the network transmission capacity
  • Logical Link Control (LLC)
    • Keep track of which frames

IEEE 802.11 Architecture

802.11 is the Wi-Fi(Wireless Fidelity) Alliance

  • Basic Service Set (BSS)
  • Extended Service Set (ESS)
    • SSID: Service Set Identifier, name of the wifi
  • Independent BSS

802.11 Access Control

  • Reliable Data Delivery
    • Wireless channels are useally unreliable
    • Mechanism is developed for error detection and contention
  • Access Control
    • For deciding which station can send
  • Security
    • Make sure the configentiality and data integrity
    • Disallowing unauthorized station to connect to the network

Threads in Wireless LANs

  • Eavesdropping
    • Due to the broadcast nature of radio communications
    • Signals can be received by any receiver within some transmission range
  • No Physical Protection
    • No physical cables

Protocol of Wireless Security

WEP Wired Equivalent Privacy

The purpose of WEP:

  • Authentication
  • Data confidentiality

Problem of WEP:
WEP is publiced at 1997 and design flawed at 2000
Authentication flaws:

  • auth in WEP is not mutual. AP does not auth itself to clients
  • Auth and encryption use the same secret key
  • Auth only at the time tries to connect to the network. After Auth, everyone can spoofing its MAC address

WPA, WPA2, WPA3 - Wifi Protected Access

New security architecture 802.11i designed to replace WEP during 2003-2004
WPA2/3 should be used

  • WPA
    • intermediate solution which can be implemented by updating the firmware of existing APs
  • WPA2
    • Long term solution
  • WPA3
    • Next generation, all WIFI6 certified routers are required to implement
  1. Phase 1: Discovery
    Discovery phase allows an STA and AP recognize each other
  2. Phase 2: Authentication
  • Only authorized STAs can use the network
  • STA is assured that the network is legitimate
    Extensible Authentication Protocol(EAP) is used
  1. Phase 3: Key Management Phase
  • Pairwise keys used for communication between an STA and an AP
  • Group keys used for multicast communication
  1. Phase 4: Protected Data Transfer Phase
  • TKIP

    • for WPA: Temporal Key Integrity Protocol
    • allows old device update firmware
    • 64-bit message to replace the CRC code
    • Still use RC4 encryption algorithm
  • AES-CCMP

    • for WPA2: Counter mode-CBC MAC protocol
    • Design for new hardware
    • Cipher-block-chaining message Authentication code to provide data integrity
    • AES algorithm for encryption
EAP

Three roles of EAP

  1. Supplicant: STA
  2. Authenticator: AP
  3. Authentication server(AS): a separate device or the AP

Sub-phases:
Connect to AS -> EAP exchange -> Secure key delivery(AS generates a master session key and sends it to STA)