2024-10-31 20:18:37 +01:00
<!DOCTYPE html> < html lang = "fr" >
< head > < meta charset = "utf-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1, user-scalable=no" > < title > Serveur Debian Buster carte mère ASRock QC5000M - YannStatic< / title >
< meta name = "description" content = "ASRock QC5000M Quad-Core APU" >
< link rel = "canonical" href = "https://static.rnmkcy.eu/2021/06/19/Serveur-Debian-Buster-Carte-ASRock-QC5000M.html" > < link rel = "alternate" type = "application/rss+xml" title = "YannStatic" href = "/feed.xml" >
<!-- - include head/favicon.html - -->
< link rel = "shortcut icon" type = "image/png" href = "/assets/favicon/favicon.png" > < link rel = "stylesheet" href = "/assets/css/main.css" > < link rel = "stylesheet" href = "https://use.fontawesome.com/releases/v5.0.13/css/all.css" > <!-- start custom head snippets --> < link rel = "stylesheet" href = "/assets/css/expand.css" >
<!-- end custom head snippets --> < script > ( f u n c t i o n ( ) {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length ; i + + ) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb & & (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining < = 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length ; i + + ) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length ; i + + ) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length ; i + + ) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length ; i + + ) {
for (flag = false, j = 0; j < mData.length ; j + + ) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length ; i + + ) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi & & (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length ; j + + ) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag & & cbs & & cbs.length > 0) {
for (j = 0; j < cbs.length ; j + + ) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length ; i + + ) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback & & (qi.load || qi.callbacks.push(callback));
callback & & (qi.load & & callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length ; i + + ) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) & & (node = createNode('script', { src: url }));
(type === 'css') & & (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
< / script > < script >
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
jquery: '/assets/js/jquery.min.js',
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
gitalk: {
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
},
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
< / script >
< / head >
< body >
< div class = "root" data-is-touch = "false" >
< div class = "layout--page js-page-root" > <!-- --> < div class = "page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto" >
< div class = "page__main-inner" > < div class = "page__header d-print-none" > < header class = "header" > < div class = "main" >
< div class = "header__title" >
< div class = "header__brand" > < svg id = "svg" version = "1.1" xmlns = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" width = "400" height = "478.9473684210526" viewBox = "0, 0, 400,478.9473684210526" > < g id = "svgg" > < path id = "path0" d = "M308.400 56 . 805 C 306 . 970 56 . 966 , 303 . 280 57 . 385 , 300 . 200 57 . 738 C 290 . 906 58 . 803 , 278 . 299 59 . 676 , 269 . 200 59 . 887 L 260 . 600 60 . 085 259 . 400 61 . 171 C 258 . 010 62 . 428 , 256 . 198 63 . 600 , 255 . 645 63 . 600 C 255 . 070 63 . 600 , 252 . 887 65 . 897 , 252 . 598 66 . 806 C 252 . 460 67 . 243 , 252 . 206 67 . 600 , 252 . 034 67 . 600 C 251 . 397 67 . 600 , 247 . 206 71 . 509 , 247 . 202 72 . 107 C 247 . 201 72 . 275 , 246 . 390 73 . 190 , 245 . 400 74 . 138 C 243 . 961 75 . 517 , 243 . 598 76 . 137 , 243 . 592 77 . 231 C 243 . 579 79 . 293 , 241 . 785 83 . 966 , 240 . 470 85 . 364 C 239 . 176 86 . 740 , 238 . 522 88 . 365 , 237 . 991 91 . 521 C 237 . 631 93 . 665 , 236 . 114 97 . 200 , 235 . 554 97 . 200 C 234 . 938 97 . 200 , 232 . 737 102 . 354 , 232 . 450 104 . 472 C 232 . 158 106 . 625 , 230 . 879 109 . 226 , 229 . 535 110 . 400 C 228 . 933 110 . 926 , 228 . 171 113 . 162 , 226 . 434 119 . 500 C 226 . 178 120 . 435 , 225 . 795 121 . 200 , 225 . 584 121 . 200 C 225 . 373 121 . 200 , 225 . 200 121 . 476 , 225 . 200 121 . 813 C 225 . 200 122 . 149 , 224 . 885 122 . 541 , 224 . 500 122 . 683 C 223 . 606 123 . 013 , 223 . 214 123 . 593 , 223 . 204 124 . 600 C 223 . 183 126 . 555 , 220 . 763 132 . 911 , 219 . 410 134 . 562 C 218 . 443 135 . 742 , 217 . 876 136 . 956 , 217 . 599 138 . 440 C 217 . 041 141 . 424 , 215 . 177 146 . 434 , 214 . 532 146 . 681 C 214 . 240 146 . 794 , 214 . 000 147 . 055 , 214 . 000 147 . 261 C 214 . 000 147 . 467 , 213 . 550 148 . 086 , 213 . 000 148 . 636 C 212 . 450 149 . 186 , 212 . 000 149 . 893 , 212 . 000 150 . 208 C 212 . 000 151 . 386 , 208 . 441 154 . 450 , 207 . 597 153 . 998 C 206 . 319 153 . 315 , 204 . 913 150 . 379 , 204 . 633 147 . 811 C 204 . 365 145 . 357 , 202 . 848 142 . 147 , 201 . 759 141 . 729 C 200 . 967 141 . 425 , 199 . 200 137 . 451 , 199 . 200 135 . 974 C 199 . 200 134 . 629 , 198 . 435 133 . 224 , 196 . 660 131 . 311 C 195 . 363 129 . 913 , 194 . 572 128 . 123 , 193 . 870 125 . 000 C 193 . 623 123 . 900 , 193 . 236 122 . 793 , 193 . 010 122 . 540 C 190 . 863 120 . 133 , 190 . 147 118 . 880 , 188 . 978 115 . 481 C 188 . 100 112 . 928 , 187 . 151 111 . 003 , 186 . 254 109 . 955 C 185 . 358 108 . 908 , 184 . 518 107 . 204 , 183 . 847 105 . 073 C 183 . 280 103 . 273 , 182 . 497 101 . 329 , 182 . 108 100 . 753 C 181 . 719 100 . 177 , 180 . 904 98 . 997 , 180 . 298 98 . 131 C 179 . 693 97 . 265 , 178 . 939 95 . 576 , 178 . 624 94 . 378 C 178 . 041 92 . 159 , 177 . 125 90 . 326 , 175 . 023 87 . 168 C 174 . 375 86 . 196 , 173 . 619 84 . 539 , 173 . 342 83 . 486 C 172 . 800 81 . 429 , 171 . 529 79 . 567 , 170 . 131 78 . 785 C 169 . 654 78 . 517 , 168 . 697 77 . 511 , 168 . 006 76 . 549 C 167 . 316 75 . 587 , 166 . 594 74 . 800 , 166 . 402 74 . 800 C 166 . 210 74 . 800 , 164 . 869 73 . 633 , 163 . 421 72 . 206 C 160 . 103 68 . 936 , 161 . 107 69 . 109 , 146 . 550 69 . 301 C 133 . 437 69 . 474 , 128 . 581 70 . 162 , 126 . 618 72 . 124 C 126 . 248 72 . 495 , 125 . 462 72 . 904 , 124 . 872 73 . 033 C 124 . 282 73 . 163 , 123 . 088 73 . 536 , 122 . 219 73 . 863 C 121 . 349 74 . 191 , 119 . 028 74 . 638 , 117 . 061 74 . 858 C 113 . 514 75 . 254 , 109 . 970 76 . 350 , 108 . 782 77 . 419 C 107 . 652 78 . 436 , 100 . 146 80 . 400 , 97 . 388 80 . 400 C 95 . 775 80 . 400 , 93 . 167 81 . 360 , 91 . 200 82 . 679 C 90 . 430 83 . 195 , 89 . 113 83 . 804 , 88 . 274 84 . 031 C 85 . 875 84 . 681 , 78 . 799 90 . 910 , 74 . 400 96 . 243 L 73 . 400 97 . 456 73 . 455 106 . 028 C 73 . 526 117 . 055 , 74 . 527 121 . 238 , 77 . 820 124 . 263 C 78 . 919 125 . 273 , 80 . 400 127 . 902 , 80 . 400 128 . 842 C 80 . 400 129 . 202 , 81 . 075 130 . 256 , 81 . 900 131 . 186 C 83 . 563 133 . 059 , 85 . 497 136 . 346 , 86 . 039 138 . 216 C 86 . 233 138 . 886 , 87 . 203 140 . 207 , 88 . 196 141 . 153 C 89 . 188 142 . 098 , 90 . 000 143 . 104 , 90 . 000 143 . 388 C 90 . 000 144 . 337 , 92 . 129 148 . 594 , 92 . 869 149 . 123 C 93 . 271 149 . 410 , 93 . 600 149 . 831 , 93 . 600 150 . 059 C 93 . 600 150 . 286 , 93 . 932 150 . 771 , 94 . 337 151 . 136 C 94 . 743 151 . 501 , 95 . 598 153 . 004 , 96 . 237 154 . 475 C 96 . 877 155 . 947 , 97 . 760 157 . 351 , 98 . 200 157 . 596 C 98 . 640 157 . 841 , 99 . 900 159 . 943 , 101 . 000 162 . 267 C 102 . 207 164 . 817 , 103 . 327 166 . 644 , 103 . 825 166 . 876 C 104 . 278 167 . 087 , 105 . 065 168 . 101 , 105 . 573 169 . 130 C 107 . 658 173 . 348 , 108 . 097 174 . 093 , 110 . 006 176 . 647 C 111 . 103 178 . 114 , 112 . 000 179 . 725 , 112 . 000 180 . 227 C 112 . 000 181 . 048 , 113 . 425 183 . 163 , 114 . 678 184 . 200 C 115 . 295 184 . 711 , 117 . 396 188 . 733 , 117 . 720 190 . 022 C 117 . 855 190 . 562 , 118 . 603 191 . 633 , 119 . 381 192 . 402 C 120 . 160 193 . 171 , 121 . 496 195 . 258 , 122 . 351 197 . 039 C 123 . 206 198 . 820 , 124 . 167 200 . 378 , 124 . 487 200 . 501 C 124 . 807 200 . 624 , 125 . 953 202 . 496 , 127 . 034 204 . 662 C 128 . 114 206 . 828 , 129 . 676 209 . 299 , 130 . 505 210 . 153 C 131 . 333 211 . 007 , 132 . 124 212 . 177 , 132 . 262 212 . 753 C 132 . 618 214 . 239 , 134 . 291 217 . 048 , 136 . 288 219 . 5
" href="/">YannStatic< / a > < / div > <!-- <button class="button button - - secondary button - - circle search - button js - search - toggle"><i class="fas fa - search"></i></button> --> <!-- <li><button class="button button - - secondary button - - circle search - button js - search - toggle"><i class="fas fa - search"></i></button></li> -->
<!-- Champ de recherche -->
< div id = "searchbox" class = "search search--dark" style = "visibility: visible" >
< div class = "main" >
< div class = "search__header" > < / div >
< div class = "search-bar" >
< div class = "search-box js-search-box" >
< div class = "search-box__icon-search" > < i class = "fas fa-search" > < / i > < / div >
< input id = "search-input" type = "text" / >
<!-- <div class="search - box__icon - clear js - icon - clear">
< a > < i class = "fas fa-times" > < / i > < / a >
< / div > -->
< / div >
< / div >
< / div >
< / div >
<!-- Script pointing to search - script.js -->
< script > / * !
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen ; i + + ) {
var nch = needle.charCodeAt(i);
while (j < tlen ) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) & & Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) & & Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len ; i + + ) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length & & matches . length < opt . limit ; i + + ) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) & & strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len ; i + + ) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 & & xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' & & params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object & & JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '< li > < a href = "{url}" title = "{desc}" > {title}< / a > < / li > ',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' & & options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len ; i + + ) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query & & query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
< / script >
<!-- Configuration -->
< script >
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
//searchResultTemplate: '< li > < a href = "https://static.rnmkcy.eu{url}" > {date} {title}< / a > < / li > '
searchResultTemplate: '< li > < a href = "{url}" > {date} {title}< / a > < / li > '
})
< / script >
<!-- Fin déclaration champ de recherche --> < / div > < nav class = "navigation" >
< ul > < li class = "navigation__item" > < a href = "/archive.html" > Etiquettes< / a > < / li > < li class = "navigation__item" > < a href = "/htmldoc.html" > Documents< / a > < / li > < li class = "navigation__item" > < a href = "/liens_ttrss.html" > Liens< / a > < / li > < li class = "navigation__item" > < a href = "/aide-jekyll-text-theme.html" > Aide< / a > < / li > < / ul >
< / nav > < / div >
< / header >
< / div > < div class = "page__content" > < div class = "main" > < div class = "grid grid--reverse" >
< div class = "col-main cell cell--auto" > <!-- start custom main top snippet --> < div id = "results-container" class = "search-result js-search-result" > < / div > <!-- end custom main top snippet -->
< article itemscope itemtype = "http://schema.org/Article" > < div class = "article__header" > < header > < h1 style = "color:Tomato;" > Serveur Debian Buster carte mère ASRock QC5000M< / h1 > < / header > < / div > < meta itemprop = "headline" content = "Serveur Debian Buster carte mère ASRock QC5000M" > < div class = "article__info clearfix" > < ul class = "left-col menu" > < li >
2024-11-08 14:10:33 +01:00
< a class = "button button--secondary button--pill button--sm" style = "color:#00FFFF" href = "/archive.html?tag=debian" > debian< / a >
2024-10-31 20:18:37 +01:00
< / li > < li >
2024-11-08 14:10:33 +01:00
< a class = "button button--secondary button--pill button--sm" style = "color:#00FFFF" href = "/archive.html?tag=serveur" > serveur< / a >
2024-10-31 20:18:37 +01:00
< / li > < / ul > < ul class = "right-col menu" > < li >
< i class = "far fa-calendar-alt" > < / i > < span title = "Création" style = "color:#FF00FF" > 19 juin 2021< / span >
< span title = "Modification" style = "color:#00FF7F" > 20 juin 2021< / span > < / li > < / ul > < / div > < meta itemprop = "datePublished" content = "2021-06-20T00:00:00+02:00" >
< meta itemprop = "keywords" content = "debian,serveur" > < div class = "js-article-content" >
< div class = "layout--article" > <!-- start custom article top snippet -->
< style >
#myBtn {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 99;
font-size: 12px;
font-weight: bold;
border: none;
outline: none;
background-color: white;
color: black;
cursor: pointer;
padding: 5px;
border-radius: 4px;
}
#myBtn:hover {
background-color: #555;
}
< / style >
< button onclick = "topFunction()" id = "myBtn" title = "Haut de page" > ⇧ < / button >
< script >
//Get the button
var mybutton = document.getElementById("myBtn");
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
< / script >
<!-- end custom article top snippet -->
< div class = "article__content" itemprop = "articleBody" > < details >
< summary > < b > Afficher/cacher Sommaire< / b > < / summary >
<!-- affichage sommaire -->
< div class = "toc-aside js-toc-root" > < / div >
< / details > < h1 id = "asrock-qc5000m-quad-core-apu" > ASRock QC5000M Quad-Core APU< / h1 >
< p > < a href = "/files/QC5000M.pdf" > ASRock QC5000M (pdf)< / a > < / p >
< p > < img src = "/images/asrock-qc500m.png" alt = "ASRock QC5000M" title = "ASRock QC5000M" / > < / p >
< ul >
< li > Platform
< ul >
< li > Micro ATX Form Factor< / li >
< li > Solid Capacitor design< / li >
< li > High Density Glass Fabric PCB< / li >
< / ul >
< / li >
< li > CPU
< ul >
< li > AMD FT3 Kabini A4-5050/5000 Quad-Core APU< / li >
< / ul >
< / li >
< li > Memory
< ul >
< li > 2 x DDR3 DIMM Slots< / li >
< li > Supports DDR3 1600/1333/1066 non-ECC, un-buffered memory< / li >
< li > Max. capacity of system memory: 32GB (see CAUTION1)< / li >
< / ul >
< / li >
< li > Expansion Slot
< ul >
< li > 1 x PCI Express 2.0 x16 Slot (PCIE2: x4 mode)< / li >
< li > 2 x PCI Express 2.0 x1 Slot< / li >
< / ul >
< / li >
< li > Graphics
< ul >
< li > Integrated AMD RadeonTM HD 8330 Graphics< / li >
< li > DirectX 11.1, Pixel Shader 5.0< / li >
< li > Max. shared memory 2GB< / li >
< li > Dual graphics output: support D-Sub and HDMI ports by independent display controllers (see CAUTION2)< / li >
< li > Supports HDMI with max. resolution up to 4K × 2K (4096x2160) @ 24Hz or 4K × 2K (3840x2160) @ 30Hz< / li >
< li > Supports D-Sub with max. resolution up to 2048x1536 @ 60Hz< / li >
< li > Supports Auto Lip Sync, Deep Color (12bpc), xvYCC and HBR (High Bit Rate Audio) with HDMI Port (Compliant HDMI monitor is required)< / li >
< li > Supports HDCP with HDMI Port< / li >
< li > Supports Full HD 1080p Blu-ray (BD) playback with HDMI Port< / li >
< / ul >
< / li >
< li > Audio
< ul >
< li > 7.1 CH HD Audio (Realtek ALC887 Audio Codec) * To configure 7.1 CH HD Audio, it is required to use an HD front panel audio module and enable the multi-channel audio feature through the audio driver.< / li >
< li > Supports Surge Protection (ASRock Full Spike Protection)< / li >
< li > ELNA Audio Caps< / li >
< / ul >
< / li >
< li > LAN
< ul >
< li > PCIE x1 Gigabit LAN 10/100/1000 Mb/s< / li >
< li > Rea ltek RTL 8111GR< / li >
< li > S u p p o r t s Wa k e - O n -WA N< / li >
< li > Suppor t s Wa ke- On-L A N< / li >
< li > Supports Lightning/ESD Protection (ASRock Full Spike Protection)< / li >
< li > Supports LAN Cable Detection< / li >
< li > Supports Energy Efficient Ethernet 802.3az< / li >
< li > Supports PXE< / li >
< / ul >
< / li >
< li > Rear Panel I/O
< ul >
< li > 1 x PS/2 Mouse/Keyboard Port< / li >
< li > 1 x Serial Port: COM1< / li >
< li > 1 x D-Sub Port< / li >
< li > 1 x HDMI Port< / li >
< li > 4 x USB 2.0 Ports (Supports ESD Protection (ASRock Full Spike Protection))< / li >
< li > 2 x USB 3.0 Ports (Supports ESD Protection (ASRock Full Spike Protection))< / li >
< li > 1 x RJ-45 LAN Port with LED (ACT/LINK LED and SPEED LED)< / li >
< li > HD Audio Jacks: Line in / Front Speaker / Microphone< / li >
< / ul >
< / li >
< li > Storage
< ul >
< li > 2 x SATA3 6.0 Gb/s Connectors, support NCQ, AHCI and Hot Plug< / li >
< / ul >
< / li >
< li > Connector
< ul >
< li > 1 x TPM Header< / li >
< li > 1 x CPU Fan Connector (3-pin)< / li >
< li > 2 x Chassis Fan Connectors (1 x 4-pin, 1 x 3-pin)< / li >
< li > 1 x 24 pin ATX Power Connector< / li >
< li > 1 x Front Panel Audio Connector< / li >
< li > 2 x USB 2.0 Headers (Support 4 USB 2.0 ports) (Supports ESD Protection (ASRock Full Spike Protection))< / li >
< / ul >
< / li >
< li > BIOS Feature
< ul >
< li > 32Mb AMI UEFI Legal BIOS with multilingual GUI support< / li >
< li > Supports “Plug and Play”< / li >
< li > ACPI 1.1 compliance wake up events< / li >
< li > SMBIOS 2.3.1 support< / li >
< li > DRAM Voltage multi-adjustment< / li >
< / ul >
< / li >
< li > HardwareMonitor
< ul >
< li > CPU/Chassis temperature sensing< / li >
< li > CPU/Chassis Fan Tachometer< / li >
< li > CPU/Chassis Quiet Fan< / li >
< li > CPU/Chassis Fan multi-speed control< / li >
< li > Voltage monitoring: +12V, +5V, +3.3V, Vcore< / li >
< / ul >
< / li >
< li > OS
< ul >
< li > Microsoft® Windows® 10 64-bit / 8.1 32-bit / 8.1 64-bit / 8 32-bit / 8 64-bit / 7 32-bit / 7 64-bit / XP 32-bit / XP 64-bit*< / li >
< li > USB 3.0 is not supported by Windows® XP* For the updated Windows® 10 driver, please visit ASRock’ s website for details: http://www.asrock.com< / li >
< / ul >
< / li >
< li > Certifications
< ul >
< li > FCC, CE, WHQL< / li >
< li > ErP/EuP ready (ErP/EuP ready power supply is required)< / li >
< / ul >
< / li >
< / ul >
< h2 id = "debian-buster" > Debian Buster< / h2 >
< p > < img src = "/images/debian-buster-logo1.png" alt = "" width = "100" / > < / p >
< h3 id = "partitionnement-du-disque" > Partitionnement du disque< / h3 >
< p > < em > Utilisation d’ une clé Parted bootable.< / em > < / p >
< ul >
< li > 2MB, type EF02 (BIOS partition). Utilisé par GRUB2/BIOS-GPT. (/dev/sda1)< / li >
< li > 512MB, type 8300 (Linux). Pour le boot linux /boot (/dev/sda2)< / li >
< li > 4GB, type 8200 (swap). Partition swap (en dehors de lvm). (/dev/sda3)< / li >
< li > Espace restant, type 8E00 (LVM). Pour le root / et /home. (/dev/sda4).< / li >
< / ul >
< p > Partitionnement du reste du disque SSD 120G GPT + LVM< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > gdisk /dev/sda
< / code > < / pre > < / div > < / div >
< p > On passe en mode expert : x< br / >
On efface tout : z< br / >
On relance gdisk< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > gdisk /dev/sda
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > GPT fdisk (gdisk) version 0.8.6
Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries.
Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y
Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-31457246, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-31457246, default = 31457246) or {+-}size{KMGTP}: +2M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): ef02
Changed type of partition to 'BIOS boot partition'
Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-31457246, default = 6144) or {+-}size{KMGTP}:
Last sector (6144-31457246, default = 31457246) or {+-}size{KMGTP}: +512M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8300
Changed type of partition to 'Linux filesystem'
Command (? for help): n
Partition number (3-128, default 3): 3
First sector (34-31457246, default = 210944) or {+-}size{KMGTP}:
Last sector (210944-31457246, default = 31457246) or {+-}size{KMGTP}: +2G
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8200
Changed type of partition to 'Linux swap'
Command (? for help): n
Partition number (4-128, default 4):
First sector (34-31457246, default = 4405248) or {+-}size{KMGTP}:
Last sector (4405248-31457246, default = 31457246) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8e00
Changed type of partition to 'Linux LVM'
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.
< / code > < / pre > < / div > < / div >
< h3 id = "installation-debian-10" > Installation debian 10< / h3 >
< ul >
< li > Boot et choix par F11 → USB CBM (NE PAS SELECTIONNER UEFI)< / li >
< li > Installation effectuée à partir d’ une clé USB bootable , fichier ISO : < strong > firmware-10.9.0-amd64-netinst.iso< / strong > < / li >
< li > Choix “partitionnement manuel”< / li >
< li > Serveur virtuel 64 bits VirtualBox : < strong > Debian Buster< / strong > < / li >
< li > machine : < strong > asrock< / strong > < / li >
< li > domaine :< / li >
< li > root : < strong > ytreu49< / strong > < / li >
< li > Utilisateur : < strong > asuser< / strong > < / li >
< li > Mot de passe : < strong > asuser49< / strong > < / li >
< li > Adresse IP : < strong > 192.168.0.45< / strong > < / li >
< li > Accès
< ul >
< li > SSH : < strong > ssh bust@192.168.0.45< / strong > < / li >
< li >
< s > SSH + clé : **ssh -i ~/.ssh/vbox-vmbust-ed25519 bust@192.168.0.49** (facultatif)< / s >
< / li >
< li >
< s > Transfert de fichier : **scp -P 55022 -i ~/.ssh/vbox-vmbust-ed25519 fichiera fichierb bust@192.168.0.49:/home/bust** (facultatif)< / s >
< / li >
< / ul >
< / li >
< / ul >
< p > Partitionnement< br / >
Disque SCSI1(0,0,0)(sda) 120.0 GB< / p >
< table >
< thead >
< tr >
< th > Partition< / th >
< th > Taille< / th >
< th > _< / th >
< th > Type< / th >
< th > Commentaire< / th >
< th > _< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > n°1< / td >
< td > 2.1 MB< / td >
< td > K< / td >
< td > biosgrub Bios< / td >
< td > boot pa< / td >
< td > < / td >
< / tr >
< tr >
< td > n°2< / td >
< td > 536.9 MB< / td >
< td > < / td >
< td > ext2< / td >
< td > boot< / td >
< td > /boot< / td >
< / tr >
< tr >
< td > n°3< / td >
< td > 4.3 GB< / td >
< td > F< / td >
< td > swap< / td >
< td > Linux swap< / td >
< td > swap< / td >
< / tr >
< tr >
< td > n°4< / td >
< td > 115.2 GB< / td >
< td > K< / td >
< td > lvm< / td >
< td > Linux lvm< / td >
< td > < / td >
< / tr >
< / tbody >
< / table >
< p > Configurer le gestionnaire de voulumes logiques (LVM)< br / >
Ecrire les modifications sur les disques et configurer LVM ? Oui< br / >
Créer un groupe de volumes : < strong > asr-vg< / strong > < br / >
Choisir le périphériques pour le nouveau groupe : < strong > /dev/sda4< / strong > < br / >
Créer un volume logique < strong > root< / strong > de 10GB< br / >
Créer un volume logique < strong > home< / strong > de 10GB< br / >
Terminer< br / >
Partitionnement des volumes logiques< / p >
< table >
< thead >
< tr >
< th > Partition< / th >
< th > Taille< / th >
< th > _< / th >
< th > Type< / th >
< th > Commentaire< / th >
< th > _< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > n°1< / td >
< td > 10.0 GB< / td >
< td > F< / td >
< td > ext4< / td >
< td > < / td >
< td > /home< / td >
< / tr >
< tr >
< td > n°2< / td >
< td > 10.0 GB< / td >
< td > F< / td >
< td > ext4< / td >
< td > < / td >
< td > /< / td >
< / tr >
< / tbody >
< / table >
< p > Sélection des logiciels< / p >
< ul >
< li > serveur SSH< / li >
< li > utilitaires usuels du système< / li >
< / ul >
< p > Oter la clé après installation pour le reboot< br / >
Se connecter en root< br / >
Relever adresse IP : 192.168.0.34< br / >
Adresse Mac enp3s0 70:85:c2:53:cb:80< / p >
< p > < strong > Erreurs< / strong > < / p >
< p > Message erreur< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > [ 1281.828853] ICMPv6: RA: ndisc_router_discovery failed to add default route
< / code > < / pre > < / div > < / div >
< p > Correction, désactiver l’ annonce des routes : < code class = "language-plaintext highlighter-rouge" > sudo nano /etc/sysctl.conf< / code > < br / >
Ajouter < code class = "language-plaintext highlighter-rouge" > net.ipv6.conf.enp3s0.accept_ra=0< / code > < br / >
Puis < code class = "language-plaintext highlighter-rouge" > sudo sysctl -p< / code > pour une validation immédiate< br / >
< em > < code class = "language-plaintext highlighter-rouge" > enp3s0< / code > est l’ interface réseau concerné< / em > < / p >
< p > < strong > carte graphique< / strong > < br / >
Dans le journal de boot< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > [ 5.588159] [drm:radeon_pci_probe [radeon]] *ERROR* radeon kernel modesetting for R600 or later requires firmware-amd-graphics.
< / code > < / pre > < / div > < / div >
< p > Il faut installer un firmware et redémarrer< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > apt update
apt install firmware-amd-graphics
reboot
< / code > < / pre > < / div > < / div >
< h3 id = "adressage-ipv6" > Adressage ipv6< / h3 >
< p > < img src = "/images/ipv6.png" alt = "ipv6" width = "50" / > < / p >
< p > inet6 fe80::7285:c2ff:fe53:cb80/64 scope link
Mac Adress : 70:85:c2:53:cb:80< / p >
< p > La carte n’ est joignable de l’ internet que par son adresse IPV6< br / >
NextHop Freebox permet d’ attribuer une adresse IPV6< / p >
< p > Prefixe : < strong > 2a01:e0a:2de:2c74::/64< / strong > < br / >
Next Hop: < strong > fe80::7285:c2ff:fe53:cb80< / strong > < br / >
Passerelle IPV6 Box : < strong > fe80::8e97:eaff:fe39:66d6< / strong > < / p >
< p > Modifier interface réseau debian< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo nano /etc/network/interfaces
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > # Configuration static ipv4/ipv6
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug enp3s0
iface enp3s0 inet static
address 192.168.0.34
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.254
# This is an autoconfigured IPv6 interface
iface enp3s0 inet6 static
address 2a01:e0a:2de:2c74::1
netmask 64
post-up ip -6 route add default via fe80::8e97:eaff:fe39:66d6 dev enp3s0
< / code > < / pre > < / div > < / div >
< p > Redémarrer la machine< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo systemctl reboot
< / code > < / pre > < / div > < / div >
< p > Après reboot, connexion SSH< br / >
Vérifier adresses IP V4 et V6< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ip addr
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > 1: lo: < LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp3s0: < BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 70:85:c2:53:cb:80 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.34/24 brd 192.168.0.255 scope global enp3s0
valid_lft forever preferred_lft forever
inet6 2a01:e0a:2de:2c74::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::7285:c2ff:fe53:cb80/64 scope link
valid_lft forever preferred_lft forever
< / code > < / pre > < / div > < / div >
< p > Vérifier avec un autre poste sur le même réseau local< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ping -6 -c5 2a01:e0a:2de:2c74::1
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > PING 2a01:e0a:2de:2c74::1(2a01:e0a:2de:2c74::1) 56 octets de données
64 octets de 2a01:e0a:2de:2c74::1 : icmp_seq=1 ttl=48 temps=56.8 ms
64 octets de 2a01:e0a:2de:2c74::1 : icmp_seq=2 ttl=48 temps=57.5 ms
64 octets de 2a01:e0a:2de:2c74::1 : icmp_seq=3 ttl=48 temps=55.9 ms
64 octets de 2a01:e0a:2de:2c74::1 : icmp_seq=4 ttl=48 temps=57.1 ms
64 octets de 2a01:e0a:2de:2c74::1 : icmp_seq=5 ttl=48 temps=56.5 ms
--- statistiques ping 2a01:e0a:2de:2c74::1 ---
5 paquets transmis, 5 reçus, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 55.937/56.749/57.471/0.520 ms
< / code > < / pre > < / div > < / div >
< p > Mise à jour< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > apt update & & apt upgrade -y
< / code > < / pre > < / div > < / div >
< p > Installer les outils et sudo< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > apt install rsync curl tmux jq figlet git sudo dnsutils net-tools tree imagemagick
< / code > < / pre > < / div > < / div >
< h3 id = "openssh--clés" > OpenSSH + Clés< / h3 >
< p > < img src = "/images/ssh_logo1.png" alt = "ssh" width = "100" / > +< img src = "/images/ssh-keys.png" alt = "clés" width = "40" / > < / p >
< p > Créer un jeu de clé sur PC1 pour se connecter à l’ hôte en SSH< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/asrock
< / code > < / pre > < / div > < / div >
< p > Le déploiement de la clé publique .pub sur l’ hôte< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ssh-copy-id -i .ssh/asrock.pub asuser@192.168.0.34
< / code > < / pre > < / div > < / div >
< p > Vérifier la connexion ssh < code class = "language-plaintext highlighter-rouge" > ssh asuser@192.168.0.34< / code > et modifier le paramètre < code class = "language-plaintext highlighter-rouge" > PasswordAuthentication no< / code > ainsi que le n° de port dans le fichier < code class = "language-plaintext highlighter-rouge" > /etc/ssh/sshd_config< / code > de l’ hôte et relancer le service sshd < code class = "language-plaintext highlighter-rouge" > sudo systemctl restart sshd< / code > < br / >
Tester la connexion avec clé depuis l’ invité< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ssh -p 55034 -i ~/.ssh/asrock asuser@192.168.0.34
< / code > < / pre > < / div > < / div >
< p > Passer en root< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > su
< / code > < / pre > < / div > < / div >
< p > Visudo pour les accès root via utilisateur bust< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > echo "asuser ALL=(ALL) NOPASSWD: ALL" > > /etc/sudoers
< / code > < / pre > < / div > < / div >
< p > Motd< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo rm /etc/motd & & sudo nano /etc/motd
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > _ ____ ____ _
/ \ / ___| | _ \ ___ ___ | | __
/ _ \ \___ \ | |_) |/ _ \ / __|| |/ /
/ ___ \ ___) || _ < | (_) || (__ | <
/_/ \_\|____/ |_| \_\\___/ \___||_|\_\
___ _ _ ___ ___ | |_ _ _ __ _ _ __ __ __ _ _ ____
/ _ \ | | | | / _ \/ __|| __|| | | | / _` || '_ \ \ \/ /| | | ||_ /
| (_) || |_| || __/\__ \| |_ | |_| || (_| || | | | _ > < | |_| | / /
\___/ \__,_| \___||___/ \__| \__, | \__,_||_| |_|(_)/_/\_\ \__, |/___|
|___/ |___/
< / code > < / pre > < / div > < / div >
< p > Script ssh_rc_bash< / p >
< blockquote >
< p > ATTENTION!!! Les scripts sur connexion peuvent poser des problèmes pour des appels externes autres que ssh< / p >
< / blockquote >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > wget https://static.xoyaz.xyz/files/ssh_rc_bash
chmod +x ssh_rc_bash # rendre le bash exécutable
./ssh_rc_bash # exécution
< / code > < / pre > < / div > < / div >
< p > < img src = "/images/xoyize-asrock.png" alt = "" / > < / p >
< h3 id = "historique" > Historique< / h3 >
< p > < strong > Historique de la ligne de commande< / strong > < / p >
< p > Ajoutez la recherche d’ historique de la ligne de commande au terminal.
Tapez un début de commande précédent, puis utilisez shift + up (flèche haut) pour rechercher l’ historique filtré avec le début de la commande.< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > # Global, tout utilisateur
echo '"\e[1;2A": history-search-backward' | sudo tee -a /etc/inputrc
echo '"\e[1;2B": history-search-forward' | sudo tee -a /etc/inputrc
< / code > < / pre > < / div > < / div >
< h3 id = "date-et-heure" > Date et heure< / h3 >
< p > En mode su< br / >
Modifier le fichier < code class = "language-plaintext highlighter-rouge" > /etc/systemd/timesyncd.conf< / code > < / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > [Time]
NTP=145.238.203.14 145.238.203.10
< / code > < / pre > < / div > < / div >
< p > Configurer la zone Europe/Paris et le ntp< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > timedatectl set-timezone Europe/Paris
timedatectl set-ntp true
< / code > < / pre > < / div > < / div >
< p > Relancer le service< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > systemctl daemon-reload
systemctl restart systemd-timesyncd.service
< / code > < / pre > < / div > < / div >
< p > Vérifier la zone et l’ heure< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > timedatectl status
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > Local time: ven. 2021-06-18 11:17:30 CEST
Universal time: ven. 2021-06-18 09:17:30 UTC
RTC time: ven. 2021-06-18 09:17:30
Time zone: Europe/Paris (CEST, +0200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
< / code > < / pre > < / div > < / div >
< h3 id = "parefeu-ufw" > Parefeu UFW< / h3 >
< p > < em > < img src = "/images/ufw-logo1.png" alt = "ufw" width = "50" / > ou pare - feu simple , est une interface pour gérer les règles de pare-feu dans Arch Linux, Debian ou Ubuntu. UFW est utilisé via la ligne de commande (bien qu’ il dispose d’ interfaces graphiques disponibles), et vise à rendre la configuration du pare-feu facile (ou simple).< / em > < / p >
< p > Installation < strong > Debian / Ubuntu< / strong > < / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo apt install ufw
< / code > < / pre > < / div > < / div >
< p > < em > Par défaut, les jeux de règles d’ UFW sont vides, de sorte qu’ il n’ applique aucune règle de pare-feu, même lorsque le démon est en cours d’ exécution.< / em > < / p >
< p > Les règles< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo ufw allow 55034/tcp # port SSH , 55034
sudo ufw allow http # port 80
sudo ufw allow https # port 443
sudo ufw allow DNS # port 53
< / code > < / pre > < / div > < / div >
< p > Activer le parefeu< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo ufw enable
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
< / code > < / pre > < / div > < / div >
< p > Status< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo ufw status verbose
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
55034/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
53 (DNS) ALLOW IN Anywhere
55034/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
53 (DNS (v6)) ALLOW IN Anywhere (v6)
< / code > < / pre > < / div > < / div >
< h2 id = "nfs-et-partage" > NFS et partage< / h2 >
< p > < img src = "/images/nfs-ufw.png" alt = "" / > < br / >
< img src = "/images/nfs-new-logo.png" alt = "" width = "50" / > < em > (Network File System) est un protocole qui permet d’ accéder à des fichiers via le réseau. Il est basé sur le protocole RPC (Remote Procedure Call). Les clients montent la partition de la machine distante comme si c’ était un disque local.< / em > < / p >
< p > En mode su< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo -s
< / code > < / pre > < / div > < / div >
< h3 id = "installation-serveur-nfs" > Installation serveur NFS< / h3 >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > apt install nfs-kernel-server
< / code > < / pre > < / div > < / div >
< p > Vérification de l’ installation< / p >
< p > Exécuter rpcinfo pour confirmer que le serveur est lancé, et accepte les requêtes sur le port 2049 (UDP et TCP).< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > rpcinfo -p | grep nfs
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > 100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100003 3 udp 2049 nfs
< / code > < / pre > < / div > < / div >
< p > Vérifier que le système supporte effectivement NFS:< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > cat /proc/filesystems | grep nfs
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > nodev nfsd
< / code > < / pre > < / div > < / div >
< p > Si la commande précédente ne renvoie rien, il se peut que le module NFS ne soit pas chargé, auquel cas, il faut le charger < code class = "language-plaintext highlighter-rouge" > modprobe nfs< / code > < br / >
Enfin, vérifions que portmap attend les instructions sur le port 111< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > rpcinfo -p | grep portmap
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > 100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
< / code > < / pre > < / div > < / div >
< p > < strong > Sécurisation NFS< / strong > < / p >
< p > < img src = "/images/nfs-new-logo.png" alt = "" width = "40" / > < / p >
< p > Le protocole RPC n’ a pas la réputation d’ être bien sécurisé, mais la version 4 de NFS entend corriger ce problème, elle est donc à privilégier. Il est déconseillé d’ effectuer un partage NFS via internet, ou bien dans ce cas, opter pour un tunnel crypté.< / p >
< ul >
< li > S’ assurer que les partages sont réservés à certaines IP dans /etc/exports< / li >
< li > S’ appuyer sur rpcbind (/etc/hosts.deny et /etc/hosts.allow) pour sécuriser l’ accès au serveur NFS< / li >
< li > Configurer convenablement iptables< / li >
< / ul >
< p > < strong > hosts.deny , hosts.allow< / strong > < br / >
Tout le monde est interdit, puis le LAN est autorisé:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "nb" > echo< / span > < span class = "s2" > "rpcbind mountd nfsd statd lockd rquotad : ALL"< / span > < span class = "o" > > > < / span > /etc/hosts.deny
< span class = "nb" > echo< / span > < span class = "s2" > "rpcbind mountd nfsd statd lockd rquotad: 192.168.0."< / span > < span class = "o" > > > < / span > /etc/hosts.allow
< / code > < / pre > < / div > < / div >
< p > Par défaut, les différents services NFS (lockd, statd, mountd, etc.) demandent des assignations de ports aléatoires à partir du portmapper (portmap/rpcbind), ce qui signifie que la plupart des administrateurs doivent ouvrir une gamme de ports dans leur base de règles de pare-feu pour que NFS fonctionne.< / p >
< p > Il va donc falloir fixer les ports de ces services afin de créer les règles parefeu.< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "nb" > echo< / span > < span class = "s1" > 'STATDOPTS="--port 32765 --outgoing-port 32766"'< / span > < span class = "o" > > > < / span > /etc/default/nfs-common
< span class = "nb" > echo< / span > < span class = "s1" > 'RPCMOUNTDOPTS="-p 32767"'< / span > < span class = "o" > > > < / span > /etc/default/nfs-kernel-server
< span class = "nb" > echo< / span > < span class = "s1" > 'RPCRQUOTADOPTS="-p 32769"'< / span > < span class = "o" > > > < / span > /etc/default/quota
< / code > < / pre > < / div > < / div >
< p > Relance sysctl< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sysctl --system
< / code > < / pre > < / div > < / div >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "k" > *< / span > Applying /etc/sysctl.d/99-sysctl.conf ...
< span class = "k" > *< / span > Applying /etc/sysctl.d/protect-links.conf ...
fs.protected_hardlinks < span class = "o" > =< / span > 1
fs.protected_symlinks < span class = "o" > =< / span > 1
< span class = "k" > *< / span > Applying /etc/sysctl.conf ...
< / code > < / pre > < / div > < / div >
< p > Relancer le service< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > systemctl restart nfs-kernel-server
< / code > < / pre > < / div > < / div >
< p > < strong > NFS - Ajout des règles parefeu UFW< / strong > < / p >
< p > Voici les règles à fixer dans le parefeu< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo ufw allow from 192.168.0.0/24 to any port 111,2049,32764:32769 proto tcp
sudo ufw allow from 192.168.0.0/24 to any port 111,2049,32764:32769 proto udp
< / code > < / pre > < / div > < / div >
< p > Vérification< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo ufw status
< / code > < / pre > < / div > < / div >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > Status: active
To Action From
< span class = "nt" > --< / span > < span class = "nt" > ------< / span > < span class = "nt" > ----< / span >
55034/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
DNS ALLOW Anywhere
111,2049,32764:32769/tcp ALLOW 192.168.0.0/24
111,2049,32764:32769/udp ALLOW 192.168.0.0/24
55034/tcp < span class = "o" > (< / span > v6< span class = "o" > )< / span > ALLOW Anywhere < span class = "o" > (< / span > v6< span class = "o" > )< / span >
80/tcp < span class = "o" > (< / span > v6< span class = "o" > )< / span > ALLOW Anywhere < span class = "o" > (< / span > v6< span class = "o" > )< / span >
443/tcp < span class = "o" > (< / span > v6< span class = "o" > )< / span > ALLOW Anywhere < span class = "o" > (< / span > v6< span class = "o" > )< / span >
DNS < span class = "o" > (< / span > v6< span class = "o" > )< / span > ALLOW Anywhere < span class = "o" > (< / span > v6< span class = "o" > )< / span >
< / code > < / pre > < / div > < / div >
< h3 id = "partage" > Partage< / h3 >
< p > < strong > Côté serveur< / strong > < br / >
En mode su< br / >
Le disque à partager est paritionné LVM et on va utiliser la partie libre< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > vgs
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > VG #PV #LV #SN Attr VSize VFree
asr-vg 1 2 0 wz--n- < 116,74g 98,11g
< / code > < / pre > < / div > < / div >
< p > Création du volume logique et formatage fichier ext4< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > lvcreate -l 100%FREE -n lv-asrock asr-vg
mkfs -t ext4 /dev/asr-vg/lv-asrock
< / code > < / pre > < / div > < / div >
< p > < strong > Ajout d’ un second disque de 2To< / strong > < br / >
Créer une partition lvm 8e avec fdisk< br / >
Créer un volume physique et logique lvm< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > pvcreate /dev/sdb1 # Physical volume "/dev/sdb1" successfully created.
vgcreate vg-ext2to /dev/sdb1 # Volume group "vg-ext2to" successfully created
lvcreate -l 100%FREE -n lv-ext2to vg-ext2to # Logical volume "lv-ext2to" created.
mkfs -t ext4 /dev/vg-ext2to/lv-ext2to
< / code > < / pre > < / div > < / div >
< ul >
< li > < a href = "https://doc.ubuntu-fr.org/acl" > Les Access Control List : Gestion avancée des droits sous linux< / a > < / li >
< / ul >
< p > Installer acl< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > apt install acl
< / code > < / pre > < / div > < / div >
< blockquote >
< p > si la partition concernée par le partage est de type ext4 le support des acl est actif par défaut: l’ option de montage “acl” a été remplacée par “noacl”, qui devient donc celle à utiliser si on veut… désactiver le support des acl.< / p >
< / blockquote >
< p > < strong > Configurer le partage NFS avec SetGID< / strong > < / p >
< p > < em > Quand un répertoire est «setgidé », le comportement observé change. On ne parle alors plus de droits d’ exécution mais d’ appartenance. En effet, tous les fichiers ou sous-répertoires qui seraient créés dans un tel répertoire, appartiendraient automatiquement au groupe auquel appartient le dossier. Si plusieurs utilisateurs peuvent et/ou doivent travailler dans un même répertoire par exemple, on peut positionner le droit SETGID sur ce répertoire afin que tous les utilisateurs puissent accéder à son contenu sans restrictions liées au propriétaire qui a créé le fichier ou le sous-répertoire.< / em > < / p >
< p > Créer les dossiers qui seront partagés sur le réseau local< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > mkdir -p /asrockpart
mkdir -p /asrock2to
< / code > < / pre > < / div > < / div >
< p > Montage de la partition volume logique /dev/asr-vg/lv-asrock< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > blkid | grep "/dev/mapper/asr--vg-lv--asrock" # relever uuid
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > /dev/mapper/asr--vg-lv--asrock: UUID="f04f2999-cdae-42e2-b11b-af3d43e43580" TYPE="ext4"
< / code > < / pre > < / div > < / div >
< p > Ajout au fichier fstab< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > nano /etc/fstab
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > # volume logique /dev/asr-vg/lv-asrock (/dev/mapper/asr--vg-lv--asrock)
UUID=f04f2999-cdae-42e2-b11b-af3d43e43580 /asrockpart ext4 defaults 0 2
< / code > < / pre > < / div > < / div >
< p > Montage de la partition volume logique /dev/vg-ext2to/lv-ext2to< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > blkid | grep "/dev/mapper/vg--ext2to-lv--ext2to" # relever uuid
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > /dev/mapper/vg--ext2to-lv--ext2to: UUID="6dbfde4d-2c48-4269-8998-2a095ceac4b4" TYPE="ext4"
< / code > < / pre > < / div > < / div >
< p > Ajout au fichier fstab< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > nano /etc/fstab
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > # volume logique /dev/vg-ext2to/lv-ext2to (/dev/mapper/vg--ext2to-lv--ext2to)
UUID=6dbfde4d-2c48-4269-8998-2a095ceac4b4 /asrock2to ext4 defaults 0 2
< / code > < / pre > < / div > < / div >
< p > Montage manuel< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > mount -a
< / code > < / pre > < / div > < / div >
< p > < strong > Partager /asrockpart/ et /asrock2to/< / strong > < / p >
< p > indiquer au serveur les répertoires qui seront partagés, les machines qui y auront accès et les conditions de ce partage.< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > nano /etc/exports
< / code > < / pre > < / div > < / div >
< p > Ajouter en fin de fichier < strong > /etc/exports< / strong > < / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > /asrockpart 192.168.0.0/24(rw,no_subtree_check,no_root_squash)
/asrock2to 192.168.0.0/24(rw,no_subtree_check,no_root_squash)
< / code > < / pre > < / div > < / div >
< p > Exporter< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > exportfs -ar
< / code > < / pre > < / div > < / div >
< p > Pour vérifier que l’ export a bien eu lieu, taper sur le serveur NFS la commande :< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > showmount -e 192.168.0.34
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > Export list for 192.168.0.34:
/asrock2to 192.168.0.0/24
/asrockpart 192.168.0.0/24
< / code > < / pre > < / div > < / div >
< p > Nous devons configurer SetGID dans ce répertoire, comme indiqué ci-dessous.< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > chmod 2775 /asrockpart
chmod 2775 /asrock2to
< / code > < / pre > < / div > < / div >
< p > Cela a également défini les autorisations 775 sur le répertoire, de sorte que l’ utilisateur racine et le groupe défini disposent d’ autorisations complètes. Le 2 permet setgid.< / p >
< p > Ensuite, nous créons un groupe appelé ‘ local’ et modifions le répertoire /asrockpart afin que le propriétaire du groupe soit ce groupe ‘ local’ .< br / >
Nous spécifions également manuellement le GID qui sera utilisé pour le groupe en tant que 9999; il doit s’ agir d’ un < u > numéro libre sur votre client et votre serveur< / u > .< / p >
< p > En mode NON su< br / >
Exécuter < code class = "language-plaintext highlighter-rouge" > groupadd< / code > sur le client et sur le serveur, et ajouter un (ou plusieurs) utilisateur à ce groupe.< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "nb" > sudo < / span > groupadd < span class = "nt" > -g< / span > 9999 < span class = "nb" > local< / span > < span class = "c" > # sur client et serveur< / span >
< span class = "c" > # ajout utilisateur au groupe< / span >
< span class = "nb" > sudo < / span > usermod < span class = "nt" > -a< / span > < span class = "nt" > -G< / span > < span class = "nb" > local< / span > < span class = "nv" > $USER< / span > < span class = "c" > # sur client et serveur< / span >
< span class = "nb" > sudo chown< / span > < span class = "nv" > $USER< / span > .local /asrockpart < span class = "c" > # serveur uniquement< / span >
< span class = "nb" > sudo chown< / span > < span class = "nv" > $USER< / span > .local /asrock2to < span class = "c" > # serveur uniquement< / span >
< / code > < / pre > < / div > < / div >
< p > < strong > Droits ACL< / strong > < br / >
Donner les droits ACL en lecture,écriture et exécution à l’ utilisateur $USER et au groupe local< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo setfacl -Rm u:$USER:rwx,g:local:rwx /asrockpart/
sudo setfacl -Rm u:$USER:rwx,g:local:rwx /asrock2to/
< / code > < / pre > < / div > < / div >
< p class = "info" > Désormais, tous les fichiers ou répertoires créés dans < code class = "language-plaintext highlighter-rouge" > /asrockpart< / code > se verront automatiquement attribuer le propriétaire du groupe < em > ‘ local< / em > , ce qui permettra essentiellement la collaboration de groupe, car tout utilisateur appartenant au groupe < em > local< / em > pourra désormais accéder aux fichiers créés par d’ autres utilisateurs du même groupe dans le répertoire < code class = "language-plaintext highlighter-rouge" > /asrockpart< / code > < / p >
< blockquote >
< p > < strong > NE PAS OUBLIER DE SE DECONNECTER/CONNECTER< / strong > < / p >
< / blockquote >
< p > Nous pouvons confirmer que setgid est en place, comme indiqué ci-dessous, où le bit d’ exécution pour les autorisations de groupe est une minuscule. Cela passera à une majuscule S si le groupe ne dispose pas de l’ autorisation d’ exécution et que seul setgid est en place.< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ls -la /asrockpart/ # signe + pour les acl
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > [...]
drwxrwsr-x+ 3 root local 4096 juin 18 13:40 .
[...]
< / code > < / pre > < / div > < / div >
< p > < strong > Côté Client< / strong > < br / >
< a href = "https://doc.fedora-fr.org/wiki/Partage_de_disques_en_r%C3%A9seau_avec_NFS" > Partage de disques en réseau avec NFS< / a > < / p >
< p > Installer nfs-utils avec la commande< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo pacman -S nfs-utils # archlinux
sudo apt install nfs-common # debian
< / code > < / pre > < / div > < / div >
< p > Créer un point de montage NFS< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo mkdir -p /mnt/asrock
sudo mkdir -p /mnt/asrock2to
< / code > < / pre > < / div > < / div >
< p > Le partage NFS (< code class = "language-plaintext highlighter-rouge" > /etc/hosts< / code > contient la définition du serveur : < code class = "language-plaintext highlighter-rouge" > 192.168.0.46 xoyize.xyz< / code > )< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo showmount -e 192.168.0.34
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > Export list for 192.168.0.34:
/asrock2to 192.168.0.0/24
/asrockpart 192.168.0.0/24
< / code > < / pre > < / div > < / div >
< p > Montage manuel< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo mount -t nfs 192.168.0.34:/asrockpart /mnt/asrock
sudo mount -t nfs 192.168.0.34:/asrock2to /mnt/asrock2to
< / code > < / pre > < / div > < / div >
< p > Montage automatique à la demande avec timeout via fstab et x-systemd< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo nano /etc/fstab
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > 192.168.0.34:/asrockpart/ /mnt/asrock/ nfs x-systemd.automount,x-systemd.idle-timeout=300,async 0 0
192.168.0.34:/asrock2to/ /mnt/asrock2to/ nfs x-systemd.automount,x-systemd.idle-timeout=300,async 0 0
< / code > < / pre > < / div > < / div >
< p > Vérifier< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo mount -a
< / code > < / pre > < / div > < / div >
< h2 id = "domaines-et-certificats" > Domaines et certificats< / h2 >
< h3 id = "domaine-ouestyanxyz" > Domaine ouestyan.xyz< / h3 >
< p > < img src = "/images/dns-logo.png" alt = "dns" width = "30" / > < br / >
Zone dns OVH< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > $TTL 3600
@ IN SOA dns106.ovh.net. tech.ovh.net. (2021061802 86400 3600 3600000 60)
IN NS dns106.ovh.net.
IN NS ns106.ovh.net.
IN AAAA 2a01:e0a:2de:2c74::1
* IN AAAA 2a01:e0a:2de:2c74::1
< / code > < / pre > < / div > < / div >
< h3 id = "certificats-lets-encrypt" > Certificats Let’ s Encrypt< / h3 >
< p > < img src = "/images/LetsEncrypt.png" alt = "LetsEncrypt.png" width = "100" / > < br / >
Installer acme< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > cd ~
sudo apt install socat git -y # prérequis
git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install
< / code > < / pre > < / div > < / div >
< p > Déconnexion reconnexion< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > export OVH_AK="xxxxxxxxxxxxxxxxx"
export OVH_AS="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
< / code > < / pre > < / div > < / div >
< p > Domaine ouestyan.xyz< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > acme.sh --dns dns_ovh --server letsencrypt --ocsp --issue --keylength ec-384 -d 'ouestyan.xyz' -d '*.ouestyan.xyz'
< / code > < / pre > < / div > < / div >
< p > Les certificats< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > [vendredi 18 juin 2021, 16:59:18 (UTC+0200)] Your cert is in /home/asuser/.acme.sh/ouestyan.xyz_ecc/ouestyan.xyz.cer
[vendredi 18 juin 2021, 16:59:18 (UTC+0200)] Your cert key is in /home/asuser/.acme.sh/ouestyan.xyz_ecc/ouestyan.xyz.key
[vendredi 18 juin 2021, 16:59:18 (UTC+0200)] The intermediate CA cert is in /home/asuser/.acme.sh/ouestyan.xyz_ecc/ca.cer
[vendredi 18 juin 2021, 16:59:18 (UTC+0200)] And the full chain certs is there: /home/asuser/.acme.sh/ouestyan.xyz_ecc/fullchain.cer
< / code > < / pre > < / div > < / div >
< p > Installation des certificats< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo mkdir -p /etc/ssl/private/
sudo chown $USER -R /etc/ssl/private/
acme.sh --ecc --install-cert -d ouestyan.xyz --key-file /etc/ssl/private/ouestyan.xyz-key.pem --fullchain-file /etc/ssl/private/ouestyan.xyz-fullchain.pem --reloadcmd 'sudo systemctl reload nginx.service'
< / code > < / pre > < / div > < / div >
< p > Vérification et mise à jour automatique< br / >
$ < code class = "language-plaintext highlighter-rouge" > crontab -e< / code > # edite tous les jobs de l’ utilisateur en cours< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > 36 0 * * * "/home/asuser/.acme.sh"/acme.sh --cron --home "/home/asuser/.acme.sh" --renew-hook "/home/asuser/.acme.sh/acme.sh --ecc --install-cert -d ouestyan.xyz --key-file /etc/ssl/private/ouestyan.xyz-key.pem --fullchain-file /etc/ssl/private/ouestyan.xyz-fullchain.pem --reloadcmd 'sudo systemctl reload nginx.service'" > /dev/null
< / code > < / pre > < / div > < / div >
< h2 id = "nginx" > nginx< / h2 >
< p > < img src = "/images/nginx-logo.png" alt = "nginx" width = "50" / > < br / >
< em > On installe la version dans le dépôt< / em > < / p >
< p > < strong > Nginx présent dans le dépôt debian buster< / strong > < br / >
En mode su< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo -s
< / code > < / pre > < / div > < / div >
< p > Installer nginx< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > apt install nginx
< / code > < / pre > < / div > < / div >
< p > Oter le commentaire de la ligne < code class = "language-plaintext highlighter-rouge" > server_tokens off;< / code > dans la configuration de base < code class = "language-plaintext highlighter-rouge" > /etc/nginx/nginx.conf< / code > < / p >
< ul >
< li > < strong > worker_processes< / strong > : laisser < strong > auto< / strong > ou pour profiter pleinement de la puissance de votre serveur, il est recommandé de mettre autant de worker_processes que de cœurs disponibles sur votre serveur. Pour connaître le nombre de cœurs sur votre serveur, il suffit de lancer la commande : < code class = "language-plaintext highlighter-rouge" > grep processor /proc/cpuinfo | wc -l< / code > < / li >
< li > < strong > server_tokens< / strong > : pour des raisons de sécurité, il est recommandé de désactiver l’ envoi d’ informations telles que le numéro de version de votre Nginx. Pour cela, décommentez cette directive dans le bloc http.< / li >
< / ul >
< p > Relancer nginx : < code class = "language-plaintext highlighter-rouge" > systemctl restart nginx< / code > < / p >
< p > < a href = "/2021/05/04/Nextcloud_Nginx_PHP7-FPM_MariaDB_SSL-TLS.html" > Nextcloud Nginx, PHP7-FPM, MariaDB et SSL/TLS< / a > < / p >
< h3 id = "ouestyanxyz" > ouestyan.xyz< / h3 >
< p > en mode su< / p >
< p > effacer la config par défaut< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > rm /etc/nginx/sites-enabled/default
< / code > < / pre > < / div > < / div >
< p > Créer un dossier et un fichier de configuration avec le nom du domaine et le dossier racine web< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > mkdir -p /etc/nginx/conf.d/ouestyan.xyz.d
touch /etc/nginx/conf.d/ouestyan.xyz.conf
mkdir -p /var/www/default
< / code > < / pre > < / div > < / div >
< p > Le fichier de configuration web < code class = "language-plaintext highlighter-rouge" > ouestyan.xyz.conf< / code > < / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > nano /etc/nginx/conf.d/ouestyan.xyz.conf
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > server {
listen 80;
listen [::]:80;
server_name ouestyan.xyz;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ouestyan.xyz;
ssl_certificate /etc/ssl/private/ouestyan.xyz-fullchain.pem;
ssl_certificate_key /etc/ssl/private/ouestyan.xyz-key.pem;
root /var/www/default;
index index.html;
# TLS 1.3 only
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# Virtual Host Configs
include /etc/nginx/conf.d/ouestyan.xyz.d/*.conf;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/ssl/private/ouestyan.xyz-fullchain.pem;
# replace with the IP address of your resolver
resolver 127.0.0.1;
}
< / code > < / pre > < / div > < / div >
< p > Vérification et relance< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > nginx -t
systemctl restart nginx
< / code > < / pre > < / div > < / div >
< p > Image sur la page d’ accueil (facultatif)< br / >
Déposer une image (https://unsplash.com - https://www.elegantwallpapers.com) dans le dossier < code class = "language-plaintext highlighter-rouge" > /var/www/default< / code > < br / >
Créer un fichier < code class = "language-plaintext highlighter-rouge" > /var/www/default/index.html< / code > < / p >
< pre > < code class = "language-hmtl" > < !DOCTYPE html>
< html>
< head>
< meta charset="UTF-8">
< title> debsrv< /title>
< style type="text/css" media="screen" >
html {
margin:0;
padding:0;
background: url(wallpaper.jpg) no-repeat center fixed;
-webkit-background-size: cover; /* pour anciens Chrome et Safari */
background-size: cover; /* version standardisée */
}
body { color: white; }
a:link {
color: grey;
background-color: transparent;
text-decoration: none;
}
a:hover {
color: red;
background-color: transparent;
text-decoration: underline;
}
< /style>
< /head>
< body>
< h1> ouestyan.xyz< /h1>
< p> Carte mère ASRock QC5000 - debian buster.< /p>
< /body>
< /html>
< / code > < / pre >
< p > Lien https://ouestyan.xyz< br / >
< img src = "/images/ouestyan.xyz.png" alt = "" width = "500" / > < / p >
< h2 id = "nextcloud" > Nextcloud< / h2 >
< p > < a href = "/2021/05/04/Nextcloud_Nginx_PHP7-FPM_MariaDB_SSL-TLS.html" > Nextcloud Nginx, PHP7-FPM, MariaDB et SSL/TLS< / a > < / p >
< p > Nexcloud sur le domaine cloud.ouestyan.xyz avec certificats Let’ s Encrypt< / p >
< p > Le fichier de configuration web < code class = "language-plaintext highlighter-rouge" > cloud.ouestyan.xyz.conf< / code > < / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo nano /etc/nginx/conf.d/cloud.ouestyan.xyz.conf
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > upstream php-handler {
server unix:/var/run/php/nextcloud.sock;
}
server {
listen 80;
listen [::]:80;
server_name cloud.ouestyan.xyz;
# enforce https
return 301 https://$server_name:443$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.ouestyan.xyz;
# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# NOTE: some settings below might be redundant
ssl_certificate /etc/ssl/private/ouestyan.xyz-fullchain.pem;
ssl_certificate_key /etc/ssl/private/ouestyan.xyz-key.pem;
# TLS 1.3 only
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# Virtual Host Configs
include /etc/nginx/conf.d/ouestyan.xyz.d/*.conf;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/ssl/private/ouestyan.xyz-fullchain.pem;
# replace with the IP address of your resolver
resolver 127.0.0.1;
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this
# topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/nextcloud;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
# The following rule is only needed for the Social app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
location = /.well-known/carddav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
# Anything else is dynamically handled by Nextcloud
location ^~ /.well-known { return 301 /index.php$uri; }
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
}
< / code > < / pre > < / div > < / div >
< p > Relancer php-fpm< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo systemctl restart php7.4-fpm
< / code > < / pre > < / div > < / div >
< p > Vérifier et recharger nginx< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo nginx -t
sudo systemctl reload nginx
< / code > < / pre > < / div > < / div >
< p > Lancer < a href = "https://cloud.ouestyan.xyz" > https://cloud.ouestyan.xyz< / a > < / p >
< p > Poursuivre la procédure < a href = "/2021/05/04/Nextcloud_Nginx_PHP7-FPM_MariaDB_SSL-TLS.html" > Nextcloud Nginx, PHP7-FPM, MariaDB et SSL/TLS< / a > < / p >
< h3 id = "authentification-à-deux-facteurs" > Authentification à deux facteurs< / h3 >
< p > Cette activation de la double authentification passe par plusieurs étapes. La première est d’ installer une (ou plusieurs applications) permettant d’ avoir un deuxième facteur d’ authentification. Ces applications sont listées < a href = "https://apps.nextcloud.com/categories/security" > le magasin des applications Nextcloud catégorie Sécurité< / a > . Il existe plusieurs applications, chacunes d’ elles ayant une fonctionnalité précise.< / p >
< p > Installer l’ application < a href = "https://apps.nextcloud.com/apps/twofactor_totp" > TOTP two-factor provider< / a > < br / >
< img src = "/images/nextcloud.rnmkcy.eu006.png" alt = "" width = "600" / > < br / >
Ensuite se rendre dans las paramètres< br / >
< img src = "/images/nextcloud.rnmkcy.eu005.png" alt = "" width = "600" / > < br / >
Il faut sauver les code de récupération TOTP< br / >
Paramétrer les applications TOTP avec le code ou QrCode< br / >
Vérifier pour valider le passage en authorisation à deux facteurs TOTP< br / >
Se reconnecter à l’ application et après saisie login/Mot de passe , un code est exigé < br / >
< img src = "/images/nextcloud.rnmkcy.eu008.png" alt = "" width = "600" / > < / p >
< h2 id = "monitorer-un-système-linux-avec-telegraf-influxdb-et-grafana" > < a href = "/2021/06/20/InfluxDB-Telegraf-Grafana.html" > Monitorer un système linux avec Telegraf, InfluxDB et Grafana< / a > < / h2 >
< p > Créer une configuration proxy nginx grafana< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > sudo nano /etc/nginx/conf.d/ouestyan.xyz.d/proxy-grafana.conf
< / code > < / pre > < / div > < / div >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > location /grafana {
proxy_pass http://localhost:3000;
}
< / code > < / pre > < / div > < / div >
< p > Recharger nginx < code class = "language-plaintext highlighter-rouge" > sudo systemctl reload nginx< / code > < br / >
Le lien < a href = "https://ouestyan.xyz/grafana" > https://ouestyan.xyz/grafana< / a > < / p >
< / div >
< div class = "d-print-none" > < footer class = "article__footer" > < meta itemprop = "dateModified" content = "2021-06-19T00:00:00+02:00" > <!-- start custom article footer snippet -->
<!-- end custom article footer snippet -->
<!--
< div align = "right" > < a type = "application/rss+xml" href = "/feed.xml" title = "S'abonner" > < i class = "fa fa-rss fa-2x" > < / i > < / a >
  < / div >
-->
< / footer >
< div class = "article__section-navigator clearfix" > < div class = "previous" > < span > PRÉCÉDENT< / span > < a href = "/2021/06/10/Javascript-Exempls.html" > Javascript exemples< / a > < / div > < div class = "next" > < span > SUIVANT< / span > < a href = "/2021/06/20/InfluxDB-Telegraf-Grafana.html" > Monitorer un système linux avec Telegraf, InfluxDB et Grafana< / a > < / div > < / div > < / div >
< / div >
< script > ( f u n c t i o n ( ) {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
$scroll = $(scroll);
$articleContent.find('.highlight').each(function() {
$this = $(this);
$this.attr('data-lang', $this.find('code').attr('data-lang'));
});
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
$this = $(this);
$this.append($('< a class = "anchor d-print-none" aria-hidden = "true" > < / a > ').html('< i class = "fas fa-anchor" > < / i > '));
});
$articleContent.on('click', '.anchor', function() {
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
});
});
});
})();
< / script >
< / div > < section class = "page__comments d-print-none" > < / section > < / article > <!-- start custom main bottom snippet -->
<!-- end custom main bottom snippet -->
< / div >
< / div > < / div > < / div > < / div >
< / div > < script > ( f u n c t i o n ( ) {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $body = $('body'), $window = $(window);
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
var activeCount = 0;
function modal(options) {
var $root = this, visible, onChange, hideWhenWindowScroll = false;
var scrollTop;
function setOptions(options) {
var _options = options || {};
visible = _options.initialVisible === undefined ? false : show;
onChange = _options.onChange;
hideWhenWindowScroll = _options.hideWhenWindowScroll;
}
function init() {
setState(visible);
}
function setState(isShow) {
if (isShow === visible) {
return;
}
visible = isShow;
if (visible) {
activeCount++;
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
$root.addClass('modal--show');
$pageMain.scrollTop(scrollTop);
activeCount === 1 & & ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
hideWhenWindowScroll & & window.hasEvent('touchstart') & & $window.on('scroll', hide);
$window.on('keyup', handleKeyup);
} else {
activeCount > 0 & & activeCount--;
$root.removeClass('modal--show');
$window.scrollTop(scrollTop);
activeCount === 0 & & ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
hideWhenWindowScroll & & window.hasEvent('touchstart') & & $window.off('scroll', hide);
$window.off('keyup', handleKeyup);
}
onChange & & onChange(visible);
}
function show() {
setState(true);
}
function hide() {
setState(false);
}
function handleKeyup(e) {
// Char Code: 27 ESC
if (e.which === 27) {
hide();
}
}
setOptions(options);
init();
return {
show: show,
hide: hide,
$el: $root
};
}
$.fn.modal = modal;
});
})();
< / script > < div class = "modal modal--overflow page__search-modal d-print-none js-page-search-modal" > < script >
(function () {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
// search panel
var search = (window.search || (window.search = {}));
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
true : window.useDefaultSearchBox ;
var $searchModal = $('.js-page-search-modal');
var $searchToggle = $('.js-search-toggle');
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
var modalVisible = false;
search.searchModal = searchModal;
var $searchBox = null;
var $searchInput = null;
var $searchClear = null;
function getModalVisible() {
return modalVisible;
}
search.getModalVisible = getModalVisible;
function handleModalChange(visible) {
modalVisible = visible;
if (visible) {
search.onShow & & search.onShow();
useDefaultSearchBox & & $searchInput[0] & & $searchInput[0].focus();
} else {
search.onShow & & search.onHide();
useDefaultSearchBox & & $searchInput[0] & & $searchInput[0].blur();
setTimeout(function() {
useDefaultSearchBox & & ($searchInput.val(''), $searchBox.removeClass('not-empty'));
search.clear & & search.clear();
window.pageAsideAffix & & window.pageAsideAffix.refresh();
}, 400);
}
}
$searchToggle.on('click', function() {
modalVisible ? searchModal.hide() : searchModal.show();
});
// Char Code: 83 S, 191 /
$(window).on('keyup', function(e) {
if (!modalVisible & & !window.isFormElement(e.target || e.srcElement) & & (e.which === 83 || e.which === 191)) {
modalVisible || searchModal.show();
}
});
if (useDefaultSearchBox) {
$searchBox = $('.js-search-box');
$searchInput = $searchBox.children('input');
$searchClear = $searchBox.children('.js-icon-clear');
search.getSearchInput = function() {
return $searchInput.get(0);
};
search.getVal = function() {
return $searchInput.val();
};
search.setVal = function(val) {
$searchInput.val(val);
};
$searchInput.on('focus', function() {
$(this).addClass('focus');
});
$searchInput.on('blur', function() {
$(this).removeClass('focus');
});
$searchInput.on('input', window.throttle(function() {
var val = $(this).val();
if (val === '' || typeof val !== 'string') {
search.clear & & search.clear();
} else {
$searchBox.addClass('not-empty');
search.onInputNotEmpty & & search.onInputNotEmpty(val);
}
}, 400));
$searchClear.on('click', function() {
$searchInput.val(''); $searchBox.removeClass('not-empty');
search.clear & & search.clear();
});
}
});
})();
< / script > < div class = "search search--dark" >
< div class = "main" >
< div class = "search__header" > Recherche< / div >
< div class = "search-bar" >
< div class = "search-box js-search-box" >
< div class = "search-box__icon-search" > < i class = "fas fa-search" > < / i > < / div >
< input id = "search-input" type = "text" / >
< div class = "search-box__icon-clear js-icon-clear" >
< a > < i class = "fas fa-times" > < / i > < / a >
< / div >
< / div >
< button class = "button button--theme-dark button--pill search__cancel js-search-toggle" >
Annuler< / button >
< / div >
< div id = "results-container" class = "search-result js-search-result" > < / div >
< / div >
< / div >
<!-- Script pointing to search - script.js -->
< script > / * !
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen ; i + + ) {
var nch = needle.charCodeAt(i);
while (j < tlen ) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) & & Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) & & Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len ; i + + ) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length & & matches . length < opt . limit ; i + + ) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) & & strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len ; i + + ) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 & & xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' & & params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object & & JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '< li > < a href = "{url}" title = "{desc}" > {title}< / a > < / li > ',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' & & options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len ; i + + ) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query & & query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
< / script >
<!-- Configuration -->
< script >
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
noResultsText: '< p > Aucun résultat!< / p > ',
json: '/search.json',
searchResultTemplate: '< li > < a href = "{url}" > {date} {title}< / a > (Création {create})< / li > '
})
< / script >
< / div > < / div >
< script > ( f u n c t i o n ( ) {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function scrollToAnchor(anchor, duration, callback) {
var $root = this;
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
callback & & callback();
});
}
$.fn.scrollToAnchor = scrollToAnchor;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function affix(options) {
var $root = this, $window = $(window), $scrollTarget, $scroll,
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
hasInit = false, curState;
function setOptions(options) {
var _options = options || {};
_options.offsetBottom & & (offsetBottom = _options.offsetBottom);
_options.scrollTarget & & (scrollTarget = _options.scrollTarget);
_options.scroll & & (scroll = _options.scroll);
_options.disabled !== undefined & & (disabled = _options.disabled);
$scrollTarget = $(scrollTarget);
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
$scroll = $(scroll);
}
function preCalc() {
top();
rootHeight = $root.outerHeight();
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
rootLeft = $root.offset().left;
}
function calc(needPreCalc) {
needPreCalc & & preCalc();
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
rootBottomTop = scrollBottom - rootTop;
}
function top() {
if (curState !== 'top') {
$root.removeClass('fixed').css({
left: 0,
top: 0
});
curState = 'top';
}
}
function fixed() {
if (curState !== 'fixed') {
$root.addClass('fixed').css({
left: rootLeft + 'px',
top: 0
});
curState = 'fixed';
}
}
function bottom() {
if (curState !== 'bottom') {
$root.removeClass('fixed').css({
left: 0,
top: rootBottomTop + 'px'
});
curState = 'bottom';
}
}
function setState() {
var scrollTop = $scrollTarget.scrollTop();
if (scrollTop >= rootTop & & scrollTop < = scrollBottom) {
fixed();
} else if (scrollTop < rootTop ) {
top();
} else {
bottom();
}
}
function init() {
if(!hasInit) {
var interval, timeout;
calc(true); setState();
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState();
});
$window.on('resize', function() {
disabled || (calc(true), setState());
});
hasInit = true;
}
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions,
refresh: function() {
calc(true, { animation: false }); setState();
}
};
}
$.fn.affix = affix;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function toc(options) {
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('< ul class = "toc toc--ellipsis" > < / ul > '), $tocLi, $headings, $activeLast, $activeCur,
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
function setOptions(options) {
var _options = options || {};
_options.selectors & & (selectors = _options.selectors);
_options.container & & (container = _options.container);
_options.scrollTarget & & (scrollTarget = _options.scrollTarget);
_options.scroller & & (scroller = _options.scroller);
_options.disabled !== undefined & & (disabled = _options.disabled);
$headings = $(container).find(selectors).filter('[id]');
$scrollTarget = $(scrollTarget);
$scroller = $(scroller);
}
function calc() {
headingsPos = [];
$headings.each(function() {
headingsPos.push(Math.floor($(this).position().top));
});
}
function setState(element, disabled) {
var scrollTop = $scrollTarget.scrollTop(), i;
if (disabled || !headingsPos || headingsPos.length < 1 ) { return ; }
if (element) {
$activeCur = element;
} else {
for (i = 0; i < headingsPos.length ; i + + ) {
if (scrollTop >= headingsPos[i]) {
$activeCur = $tocLi.eq(i);
} else {
$activeCur || ($activeCur = $tocLi.eq(i));
break;
}
}
}
$activeLast & & $activeLast.removeClass('active');
($activeLast = $activeCur).addClass('active');
}
function render() {
if(!hasRendered) {
$root.append($tocUl);
$headings.each(function() {
var $this = $(this);
$tocUl.append($('< li > < / li > ').addClass('toc-' + $this.prop('tagName').toLowerCase())
.append($('< a > < / a > ').text($this.text()).attr('href', '#' + $this.prop('id'))));
});
$tocLi = $tocUl.children('li');
$tocUl.on('click', 'a', function(e) {
e.preventDefault();
var $this = $(this);
scrolling = true;
setState($this.parent());
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
scrolling = false;
});
});
}
hasRendered = true;
}
function init() {
var interval, timeout;
if(!hasInit) {
render(); calc(); setState(null, scrolling);
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState(null, scrolling);
});
$window.on('resize', window.throttle(function() {
if (!disabled) {
render(); calc(); setState(null, scrolling);
}
}, 100));
}
hasInit = true;
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions
};
}
$.fn.toc = toc;
});
})();
/*(function () {
})();*/
< / script > < script >
/* toc must before affix, since affix need to konw toc' height. */(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window);
var $articleContent = $('.js-article-content');
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
var toc;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
function disabled() {
return $col2.css('display') === 'none' || !hasToc;
}
tocDisabled = disabled();
toc = $tocRoot.toc({
selectors: TOC_SELECTOR,
container: $articleContent,
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
tocDisabled = disabled();
toc & & toc.setOptions({
disabled: tocDisabled
});
}, 100));
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window), $pageFooter = $('.js-page-footer');
var $pageAside = $('.js-page-aside');
var affix;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
affix = $pageAside.affix({
offsetBottom: $pageFooter.outerHeight(),
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
scroll: hasSidebar ? $('.js-page-main').children() : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
affix & & affix.setOptions({
disabled: tocDisabled
});
}, 100));
window.pageAsideAffix = affix;
});
})();
< / script > <!-- -->
< / div >
< script > ( f u n c t i o n ( ) {
var $root = document.getElementsByClassName('root')[0];
if (window.hasEvent('touchstart')) {
$root.dataset.isTouch = true;
document.addEventListener('touchstart', function(){}, false);
}
})();
< / script >
< / body >
< / html >